NL3D::CZoneTgtSmoother Class Reference

#include <zone_tgt_smoother.h>


Detailed Description

A class used to make Vertices coplanar IN or/and across zones.
Author:
Lionel Berenguier

Nevrax France

Date:
2000

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, CVertexInfoTVertexMap

Private Attributes

TVertexMap VertexMap


Member Typedef Documentation

typedef TVertexMap::iterator NL3D::CZoneTgtSmoother::ItVertexMap [private]
 

Definition at line 109 of file zone_tgt_smoother.h.

typedef std::map<sint, CVertexInfo> NL3D::CZoneTgtSmoother::TVertexMap [private]
 

Definition at line 108 of file zone_tgt_smoother.h.


Constructor & Destructor Documentation

NL3D::CZoneTgtSmoother::CZoneTgtSmoother  )  [inline]
 

Constructor.

Definition at line 53 of file zone_tgt_smoother.h.

00053 {}


Member Function Documentation

void NL3D::CZoneTgtSmoother::makeVerticesCoplanar std::vector< CZoneInfo > &  zones  ) 
 

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 }


Field Documentation

TVertexMap NL3D::CZoneTgtSmoother::VertexMap [private]
 

Definition at line 112 of file zone_tgt_smoother.h.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 08:36:40 2004 for NeL by doxygen 1.3.6