#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. |