#include <zone_tgt_smoother.h>
Nevrax France
Definition at line 48 of file zone_tgt_smoother.h.
Public Member Functions | |
| CZoneTgtSmoother () | |
| Constructor. | |
| void | makeVerticesCoplanar (std::vector< CZoneInfo > &zones) |
| Doit method. zones are modified. zones[0] is the center zones. Other are border zones. | |
Private Types | |
| typedef TVertexMap::iterator | ItVertexMap |
| typedef std::map< sint, CVertexInfo > | TVertexMap |
Private Attributes | |
| TVertexMap | VertexMap |
|
|
Definition at line 109 of file zone_tgt_smoother.h. |
|
|
Definition at line 108 of file zone_tgt_smoother.h. |
|
|
Constructor.
Definition at line 53 of file zone_tgt_smoother.h.
00053 {}
|
|
|
Doit method. zones are modified. zones[0] is the center zones. Other are border zones.
Definition at line 39 of file zone_tgt_smoother.cpp. References NL3D::CPatchInfo::BaseVertices, NL3D::CPatchInfo::BindEdges, NL3D::CBorderVertex::CurrentVertex, NL3D::CZoneTgtSmoother::CTangentId::EdgeId, NL3D::CPatchInfo::getSmoothFlag(), NL3D::CZoneTgtSmoother::CPatchId::IdVert, NL3D::CBezierPatch::Interiors, NL3D::CBorderVertex::NeighborVertex, NL3D::CBorderVertex::NeighborZoneId, nlassert, nlinfo, NLMISC::CVector::norm(), NL3D::CZoneTgtSmoother::CVertexInfo::OnBorder, NL3D::CPatchInfo::Patch, NL3D::CZoneTgtSmoother::CPatchId::Patch, NL3D::CZoneTgtSmoother::CTangentId::PatchId, NL3D::CZoneTgtSmoother::CPatchId::PatchId, NL3D::CZoneTgtSmoother::CTangentId::Patchs, NL3D::CZoneTgtSmoother::CVertexInfo::Patchs, sint, NL3D::CZoneTgtSmoother::CTangentId::Tangent, NL3D::CBezierPatch::Tangents, NL3D::CZoneTgtSmoother::CTangentId::ZoneId, and NL3D::CZoneTgtSmoother::CPatchId::ZoneId.
00040 {
00041 sint i,j, numZone;
00042 sint centerZoneId;
00043
00044 nlassert(zones.size()>=1);
00045 centerZoneId= zones[0].ZoneId;
00046
00047 // 0. CenterZone.
00048 //===============
00049 // First, make connectivity patch/vertex
00050 for(i=0;i<(sint)zones[0].Patchs.size();i++)
00051 {
00052 CPatchInfo &pa= zones[0].Patchs[i];
00053
00054 for(j=0;j<4;j++)
00055 {
00056 sint vtx= pa.BaseVertices[j];
00057 CPatchId pid;
00058 pid.ZoneId= centerZoneId;
00059 pid.PatchId= i;
00060 pid.Patch= &pa;
00061 pid.IdVert= j;
00062 VertexMap[vtx].Patchs.push_back(pid);
00063 }
00064 }
00065 // Second, what vertices of this zone are one border?
00066 for(i=0;i<(sint)zones[0].BorderVertices.size();i++)
00067 {
00068 CBorderVertex &bv= zones[0].BorderVertices[i];
00069 sint vtx= bv.CurrentVertex;
00070 VertexMap[vtx].OnBorder= true;
00071 }
00072
00073 // 1. Neighbor zones.
00074 //===================
00075 map<sint, sint> tempMap;
00076 for(numZone= 1; numZone<(sint)zones.size(); numZone++)
00077 {
00078 sint adjZoneId= zones[numZone].ZoneId;
00079
00080 tempMap.clear();
00081 // Tests which vertices points on the center zone.
00082 for(i=0;i<(sint)zones[numZone].BorderVertices.size();i++)
00083 {
00084 CBorderVertex &bv= zones[numZone].BorderVertices[i];
00085
00086 if(bv.NeighborZoneId== centerZoneId)
00087 {
00088 tempMap[bv.CurrentVertex]= bv.NeighborVertex;
00089 }
00090 }
00091 // Tests patchs which points on center zone.
00092 for(i=0;i<(sint)zones[numZone].Patchs.size();i++)
00093 {
00094 CPatchInfo &pa= zones[numZone].Patchs[i];
00095
00096 for(j=0;j<4;j++)
00097 {
00098 sint vtx= pa.BaseVertices[j];
00099 if(tempMap.find(vtx)!=tempMap.end())
00100 {
00101 CPatchId pid;
00102 pid.ZoneId= adjZoneId;
00103 pid.PatchId= i;
00104 pid.Patch= &pa;
00105 pid.IdVert= j;
00106 // Fill the vertex of the center zone.
00107 VertexMap[tempMap[vtx]].Patchs.push_back(pid);
00108 }
00109 }
00110 }
00111
00112 }
00113
00114 // 2. Process each vertex.
00115 //========================
00116 ItVertexMap itVert;
00117 for(itVert= VertexMap.begin(); itVert!=VertexMap.end(); itVert++)
00118 {
00119 CVertexInfo &vert= itVert->second;
00120
00121 // a. verify if coplanar is possible.
00122 //===================================
00123
00124 // \todo yoyo: later: do it too on non border vertices if wanted (with a normal threshold...).
00125 if(!vert.OnBorder)
00126 continue;
00127 // \todo yoyo: later: formula with 3, 5 ... patchs around the vertex.
00128 if(vert.Patchs.size()!=4)
00129 continue;
00130
00131 // Test if there is no bind 1/x on this patch, around this vertex.
00132 // \todo yoyo: later: binds should works...
00133 std::list<CPatchId>::iterator itPatch;
00134 bool bindFound= false;
00135 for(itPatch= vert.Patchs.begin(); itPatch!= vert.Patchs.end(); itPatch++)
00136 {
00137 // Tests the two edges around the vertex (before: e0, and after: e1).
00138 sint e0= (itPatch->IdVert+4-1)%4;
00139 sint e1= itPatch->IdVert;
00140
00141 if(itPatch->Patch->BindEdges[e0].NPatchs!= 1 || itPatch->Patch->BindEdges[e1].NPatchs!= 1)
00142 {
00143 bindFound= true;
00144 break;
00145 }
00146 }
00147 if(bindFound)
00148 continue;
00149
00150
00151
00152 // b. maps patchs on tangents.
00153 //=========================
00154 vector<CTangentId> tangents;
00155 for(itPatch= vert.Patchs.begin(); itPatch!= vert.Patchs.end(); itPatch++)
00156 {
00157 CPatchInfo &pa= *(itPatch->Patch);
00158 // The edges, before and after the veterx.
00159 sint edgeNum[2]= {(itPatch->IdVert+4-1)%4, itPatch->IdVert };
00160 // The tangents, before and after the veterx.
00161 sint tgtNum[2]= {(itPatch->IdVert*2+8-1)%8, itPatch->IdVert*2 };
00162
00163 // For the 2 edges around this vertex.
00164 for(sint ed= 0; ed<2;ed++)
00165 {
00166 sint patchId, zoneId, edgeId;
00167 sint tgt;
00168
00169 // get neighbor edge id.
00170 zoneId= pa.BindEdges[ edgeNum[ed] ].ZoneId;
00171 patchId= pa.BindEdges[ edgeNum[ed] ].Next[0];
00172 edgeId= pa.BindEdges[ edgeNum[ed] ].Edge[0];
00173 // Search if tangent already inserted, mapped to this "neighbor edge".
00174 for(tgt= 0; tgt<(sint)tangents.size();tgt++)
00175 {
00176 if(tangents[tgt].ZoneId==zoneId && tangents[tgt].PatchId==patchId && tangents[tgt].EdgeId==edgeId)
00177 break;
00178 }
00179 // If not found, add the tangent, and map ME to it.
00180 if(tgt==(sint)tangents.size())
00181 {
00182 CTangentId tangent;
00183 // Set OUR edge Id.
00184 tangent.ZoneId= itPatch->ZoneId;
00185 tangent.PatchId= itPatch->PatchId;
00186 tangent.EdgeId= edgeNum[ed];
00187 // Get the tangent, before or after the vertex.
00188 tangent.Tangent= pa.Patch.Tangents[ tgtNum[ed] ];
00189 // Which patchs this edge share. (0 is those which insert this tgt)
00190 tangent.Patchs[0]= &pa;
00191 tangents.push_back(tangent);
00192 }
00193 else
00194 {
00195 // Which patchs this edge share. (0 is those which access this tgt)
00196 tangents[tgt].Patchs[1]= &pa;
00197 }
00198 // Map the patch to this tangent.
00199 itPatch->Tangents[ed]= tgt;
00200
00201 }
00202 }
00203
00204 // There should be 4 tangents.
00205 if (tangents.size()!=4)
00206 {
00207 nlinfo ("ERROR: vertex %d should have 4 tangents. It got %d. (MAXINDICES +1!!)", itVert->first, tangents.size());
00208 continue;
00209 }
00210
00211
00212 // c. get the vertex.
00213 //===================
00214 CVector vertexValue;
00215 itPatch= vert.Patchs.begin();
00216 vertexValue= itPatch->Patch->Patch.Vertices[itPatch->IdVert];
00217
00218
00219 // d. project the tangents.
00220 //=========================
00221 // better coplanar than Max... (with orthogonal angles: use p0/p1).
00222 for(i=0;i<(sint)tangents.size();i++)
00223 {
00224 // For following tangents, search the opposite.
00225 // Begin at i+1 so we are sure to do this only one time.
00226 for(j=i+1;j<(sint)tangents.size();j++)
00227 {
00228 if(tangents[i].isOppositeOf(tangents[j]))
00229 {
00230 CVector &tgt0= tangents[i].Tangent;
00231 CVector &tgt1= tangents[j].Tangent;
00232 // Colinear the tangents. Must keep the length of vectors.
00233 float l0= (tgt0-vertexValue).norm();
00234 float l1= (tgt1-vertexValue).norm();
00235 // Average the tangents. Normalize them before, to keep much as possible the orientation.
00236 CVector d0= (vertexValue-tgt0).normed();
00237 CVector d1= (tgt1-vertexValue).normed();
00238 CVector dir= (d0+d1).normed();
00239
00240 // Copy to tangents.
00241 tgt0= vertexValue-dir*l0;
00242 tgt1= vertexValue+dir*l1;
00243 }
00244 }
00245 }
00246
00247
00248 // e. assign tangents to patchs, rebuild interior.
00249 //==============================
00250 for(itPatch= vert.Patchs.begin(); itPatch!= vert.Patchs.end(); itPatch++)
00251 {
00252 CPatchInfo &pa= *(itPatch->Patch);
00253 // The tangents, before and after the vertex.
00254 sint tgtNum[2]= {(itPatch->IdVert*2+8-1)%8, itPatch->IdVert*2 };
00255 sint t0= tgtNum[0];
00256 sint t1= tgtNum[1];
00257 sint smoothEdge0= pa.getSmoothFlag (t0/2);
00258 sint smoothEdge1= pa.getSmoothFlag (t1/2);
00259
00260 // Smooth this edge ?
00261 if (smoothEdge0)
00262 pa.Patch.Tangents[t0]= tangents[itPatch->Tangents[0]].Tangent;
00263 if (smoothEdge1)
00264 pa.Patch.Tangents[t1]= tangents[itPatch->Tangents[1]].Tangent;
00265
00266 // Setup the coplanared interior. just the sum of 2 vector tangents.
00267 if (smoothEdge0&&smoothEdge1)
00268 pa.Patch.Interiors[itPatch->IdVert]= pa.Patch.Tangents[t0] + pa.Patch.Tangents[t1] - vertexValue;
00269 }
00270 }
00271 }
|
|
|
Definition at line 112 of file zone_tgt_smoother.h. |
1.3.6