Integration of OCCT 6.5.0 from SVN
[occt.git] / samples / mfc / occtdemo / Simplify / Simplify_Presentation.cpp
1 // Simplify_Presentation.cpp: implementation of the Simplify_Presentation class.
2 // Simplify shape -> create a new shape based on triangulation of a given shape
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "Simplify_Presentation.h"
7
8 #include <GeomPlate_Surface.hxx>
9 #include <GeomPlate_MakeApprox.hxx>
10 #include <GeomPlate_PointConstraint.hxx>
11 #include <GeomPlate_BuildPlateSurface.hxx>
12 #include <Precision.hxx>
13 #include <TopoDS.hxx>
14 #include <TopoDS_Face.hxx>
15 #include <TopoDS_Compound.hxx>
16 #include <ShapeAnalysis_FreeBounds.hxx>
17 #include <BRep_Builder.hxx>
18 #include <BRepTools.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepMesh.hxx>
21 #include <TopExp_Explorer.hxx>
22 #include <TopLoc_Location.hxx>
23 #include <TColgp_SequenceOfPnt.hxx>
24 #include <Poly_Triangulation.hxx>
25 #include <TColgp_Array1OfPnt.hxx>
26 #include <TopoDS_Wire.hxx>
27 #include <TopTools_IndexedMapOfShape.hxx>
28 #include <TopExp.hxx>
29 #include <TopLoc_Location.hxx>
30 #include <ShapeFix_Shape.hxx>
31
32
33 #ifdef WNT
34  #define EOL "\r\n"
35 #else
36  #define EOL "\n"
37 #endif
38
39
40 // Initialization of global variable with an instance of this class
41 OCCDemo_Presentation* OCCDemo_Presentation::Current = new Simplify_Presentation;
42
43
44 //////////////////////////////////////////////////////////////////////
45 // Construction/Destruction
46 //////////////////////////////////////////////////////////////////////
47
48 Simplify_Presentation::Simplify_Presentation()
49 {
50   setName ("Simplify shape");
51 }
52
53 //=========================================================================================
54 // Sample execution
55 //=========================================================================================
56
57 void Simplify_Presentation::DoSample()
58 {
59   getAISContext()->EraseAll();
60   sample("shell1.brep");
61 }
62
63
64 //////////////////////////////////////////////////////////////////////
65 // Sample functions
66 //////////////////////////////////////////////////////////////////////
67 //================================================================
68 // Function : Simplify_Presentation::simplify
69 // Purpose  : 
70 //================================================================
71 void Simplify_Presentation::simplify(const TopoDS_Shape& aShape)
72 {
73   setResultTitle("Simplify Face");
74   setResultText(
75     "  TopoDS_Shape aShape;" EOL
76     "" EOL
77     "  // initialize aShape" EOL
78     "  //aShape = ..." EOL
79     "" EOL
80     "  // define parameter triangulation" EOL
81     "  Standard_Real aDeflection = 0.1;" EOL
82     "  " EOL
83     "  // removes all the triangulations of the faces ," EOL
84     "  //and all the polygons on the triangulations of the edges" EOL
85     "  BRepTools::Clean(aShape);" EOL
86     "  // adds a triangulation of the shape aShape with the deflection aDeflection" EOL
87     "  BRepMesh::Mesh(aShape,aDeflection);" EOL
88     "" EOL
89     "  Standard_Integer aIndex = 1, nbNodes = 0;" EOL
90     "  " EOL
91     "  // define two sequence of points" EOL
92     "  TColgp_SequenceOfPnt aPoints, aPoints1;" EOL
93     " " EOL
94     "  // triangulation" EOL
95     "  for(TopExp_Explorer aExpFace(aShape,TopAbs_FACE); aExpFace.More(); aExpFace.Next())" EOL
96     "  {  " EOL
97     "    TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL
98     "    TopLoc_Location aLocation;" EOL
99     "" EOL
100     "    // takes the triangulation of the face aFace" EOL
101     "    Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL
102     "" EOL
103     "    if(!aTr.IsNull())" EOL
104     "    { " EOL
105     "      // takes the array of nodes for this triangulation" EOL
106     "      const TColgp_Array1OfPnt& aNodes = aTr->Nodes();    " EOL
107     "      nbNodes = aNodes.Length();" EOL
108     "" EOL
109     "      for( Standard_Integer i = 1; i <= nbNodes; i++)" EOL
110     "      {" EOL
111     "        // create seguence of node points in absolute coordinate system" EOL
112     "        gp_Pnt aPnt = aNodes(i).Transformed(aLocation);" EOL
113     "        aPoints.Append(aPnt);" EOL
114     "        " EOL
115     "      }" EOL
116     "    }" EOL
117     "  }" EOL
118     " " EOL
119     "  // remove double points" EOL
120     "  nbNodes = aPoints.Length();" EOL
121     "  for( Standard_Integer i = 1; i <= nbNodes; i++)" EOL
122     "  {" EOL
123     "    gp_Pnt aPi = aPoints(i);" EOL
124     "    for( Standard_Integer j = i + 1; j < nbNodes; j++)" EOL
125     "    {" EOL
126     "      gp_Pnt aPj = aPoints(j);" EOL
127     "      if(!aPi.IsEqual(aPj,0.9))" EOL
128     "        aIndex++;" EOL
129     "    }" EOL
130     "    if(aIndex == j - 1)" EOL
131     "      aPoints1.Append(aPi);" EOL
132     "" EOL
133     "    aIndex = i + 1;" EOL
134     "  }" EOL
135     "" EOL
136     "  // find max point" EOL
137     "  aIndex = 0;" EOL
138     "  gp_Pnt aPntMax = aPoints1(1);" EOL
139     "  nbNodes = aPoints1.Length();" EOL
140     "  for(i = 2; i <= nbNodes; i++)" EOL
141     "  {" EOL
142     "    if(aPoints1(i).X() > aPntMax.X())" EOL
143     "    {" EOL
144     "      aIndex = i;" EOL
145     "      aPntMax = aPoints1(aIndex);      " EOL
146     "    } " EOL
147     "  }" EOL
148     "" EOL
149     "  // clear seguence" EOL
150     "  aPoints.Clear();" EOL
151     "" EOL
152     "  Standard_Integer nbLeftNodes = nbNodes;" EOL
153     "" EOL
154     "  // ascending sort - fill aPoints with ascending " EOL
155     "  // by X coordinate points from aPoints1" EOL
156     "  for(i = 1; i < nbNodes; i++)" EOL
157     "  {" EOL
158     "    Standard_Real aMin = aPntMax.X();" EOL
159     "    aIndex = 1;" EOL
160     "    for( Standard_Integer j = 1; j <= nbLeftNodes; j++)" EOL
161     "    {" EOL
162     "      if(aPoints1(j).X() < aMin)" EOL
163     "      {" EOL
164     "        aMin = aPoints1(j).X();" EOL
165     "        aIndex = j;" EOL
166     "      } " EOL
167     "    }" EOL
168     "    aPoints.Append(aPoints1(aIndex));" EOL
169     "    aPoints1.Remove(aIndex);" EOL
170     "    nbLeftNodes = aPoints1.Length();" EOL
171     "  }" EOL
172     "  aPoints.Append(aPntMax);" EOL
173     "" EOL
174     "  // define parameters GeomPlate_BuildPlateSurface" EOL
175     "  Standard_Integer Degree = 3;" EOL
176     "  Standard_Integer NbPtsOnCur = 10;" EOL
177     "  Standard_Integer NbIter = 3;" EOL
178     "  Standard_Integer Order = 0;" EOL
179     "  Standard_Integer MaxSeg = 9;" EOL
180     "  Standard_Integer MaxDegree = 5;" EOL
181     "  Standard_Real dmax, anApproxTol = 0.001;" EOL
182     "  Standard_Real aConstrTol = Precision::Confusion();" EOL
183     "  " EOL
184     "  // define object BuildPlateSurface" EOL
185     "  GeomPlate_BuildPlateSurface BPSurf(Degree,NbPtsOnCur,NbIter);" EOL
186     "  " EOL
187     "  // add point constraints to GeomPlate_BuildPlateSurface object" EOL
188     "  nbNodes = aPoints.Length();" EOL
189     "  for (i = 1; i <= nbNodes; i++)" EOL
190     "    BPSurf.Add(new GeomPlate_PointConstraint(aPoints(i), Order, aConstrTol));" EOL
191     "" EOL
192     "  BPSurf.Perform();" EOL
193     "" EOL
194     "  // make PlateSurface" EOL
195     "  Handle(GeomPlate_Surface) PSurf;" EOL
196     "  Handle(Geom_Surface) aSurf;" EOL
197     "  " EOL
198     "  if (BPSurf.IsDone())" EOL
199     "  {" EOL
200     "    PSurf = BPSurf.Surface();" EOL
201     "" EOL
202     "    // define parameter approximation" EOL
203     "    dmax = Max(0.01,10*BPSurf.G0Error());" EOL
204     "" EOL
205     "    // make approximation" EOL
206     "    GeomPlate_MakeApprox Mapp(PSurf,anApproxTol, MaxSeg,MaxDegree,dmax);" EOL
207     "    aSurf = Mapp.Surface();" EOL
208     "  }" EOL
209     "  else " EOL
210     "    return;" EOL
211     "" EOL
212     "  ShapeAnalysis_FreeBounds aFreeBounds(aShape, Standard_False, Standard_True);" EOL
213     "  TopoDS_Compound aClosedWires = aFreeBounds.GetClosedWires();" EOL
214     "  TopTools_IndexedMapOfShape aWires;" EOL
215     "  TopExp::MapShapes(aClosedWires, TopAbs_WIRE, aWires);" EOL
216     "  TopoDS_Wire aWire;" EOL
217     "  Standard_Integer nbWires = aWires.Extent();" EOL
218     "  if (nbWires) " EOL
219     "    aWire = TopoDS::Wire(aWires(1));" EOL
220     "  else " EOL
221     "    return;" EOL
222     "" EOL
223     "  BRep_Builder B;" EOL
224     "  TopoDS_Face aFace;" EOL
225     "  B.MakeFace(aFace, aSurf, Precision::Confusion());" EOL
226     "  B.Add(aFace, aWire);" EOL
227     "  Handle_ShapeFix_Shape sfs = new ShapeFix_Shape(aFace);" EOL
228     "  sfs->Perform();" EOL
229     "  TopoDS_Shape aFixedFace = sfs->Shape();" EOL
230     "  if (aFixedFace.IsNull()) " EOL
231     "    return;" EOL);
232
233   // define parameter triangulation
234   Standard_Real aDeflection = 0.1;
235   
236   // removes all the triangulations of the faces ,
237   //and all the polygons on the triangulations of the edges
238   BRepTools::Clean(aShape);
239   // adds a triangulation of the shape aShape with the deflection aDeflection
240   BRepMesh::Mesh(aShape,aDeflection);
241
242   Standard_Integer aIndex = 1, nbNodes = 0;
243   
244   // define two sequence of points
245   TColgp_SequenceOfPnt aPoints, aPoints1;
246  
247   // triangulation
248   for(TopExp_Explorer aExpFace(aShape,TopAbs_FACE); aExpFace.More(); aExpFace.Next())
249   {  
250     TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
251     TopLoc_Location aLocation;
252
253     // takes the triangulation of the face aFace
254     Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
255
256     if(!aTr.IsNull())
257     { 
258       // takes the array of nodes for this triangulation
259       const TColgp_Array1OfPnt& aNodes = aTr->Nodes();    
260       nbNodes = aNodes.Length();
261
262       for( Standard_Integer i = 1; i <= nbNodes; i++)
263       {
264         // create seguence of node points in absolute coordinate system
265         gp_Pnt aPnt = aNodes(i).Transformed(aLocation);
266         aPoints.Append(aPnt);
267         
268       }
269     }
270   }
271  
272   // remove double points
273   nbNodes = aPoints.Length();
274   for( Standard_Integer i = 1; i <= nbNodes; i++)
275   {
276     gp_Pnt aPi = aPoints(i);
277     for( Standard_Integer j = i + 1; j < nbNodes; j++)
278     {
279       gp_Pnt aPj = aPoints(j);
280       if(!aPi.IsEqual(aPj,0.9))
281         aIndex++;
282     }
283     if(aIndex == j - 1)
284       aPoints1.Append(aPi);
285
286     aIndex = i + 1;
287   }
288
289   // find max point
290   aIndex = 0;
291   gp_Pnt aPntMax = aPoints1(1);
292   nbNodes = aPoints1.Length();
293   for(i = 2; i <= nbNodes; i++)
294   {
295     if(aPoints1(i).X() > aPntMax.X())
296     {
297       aIndex = i;
298       aPntMax = aPoints1(aIndex);      
299     } 
300   }
301
302   // clear seguence
303   aPoints.Clear();
304
305   Standard_Integer nbLeftNodes = nbNodes;
306
307   // ascending sort - fill aPoints with ascending 
308   // by X coordinate points from aPoints1
309   for(i = 1; i < nbNodes; i++)
310   {
311     Standard_Real aMin = aPntMax.X();
312     aIndex = 1;
313     for( Standard_Integer j = 1; j <= nbLeftNodes; j++)
314     {
315       if(aPoints1(j).X() < aMin)
316       {
317         aMin = aPoints1(j).X();
318         aIndex = j;
319       } 
320     }
321     aPoints.Append(aPoints1(aIndex));
322     aPoints1.Remove(aIndex);
323     nbLeftNodes = aPoints1.Length();
324   }
325   aPoints.Append(aPntMax);
326
327   // define parameters GeomPlate_BuildPlateSurface
328   Standard_Integer Degree = 3;
329   Standard_Integer NbPtsOnCur = 10;
330   Standard_Integer NbIter = 3;
331   Standard_Integer Order = 0;
332   Standard_Integer MaxSeg = 9;
333   Standard_Integer MaxDegree = 5;
334   Standard_Real dmax, anApproxTol = 0.001;
335   Standard_Real aConstrTol = Precision::Confusion();
336   
337   // define object BuildPlateSurface
338   GeomPlate_BuildPlateSurface BPSurf(Degree,NbPtsOnCur,NbIter);
339   
340   // add point constraints to GeomPlate_BuildPlateSurface object
341   nbNodes = aPoints.Length();
342   for (i = 1; i <= nbNodes; i++)
343     BPSurf.Add(new GeomPlate_PointConstraint(aPoints(i), Order, aConstrTol));
344
345   BPSurf.Perform();
346
347   // make PlateSurface
348   Handle(GeomPlate_Surface) PSurf;
349   Handle(Geom_Surface) aSurf;
350   
351   if (BPSurf.IsDone())
352   {
353     PSurf = BPSurf.Surface();
354
355     // define parameter approximation
356     dmax = Max(0.01,10*BPSurf.G0Error());
357
358     // make approximation
359     GeomPlate_MakeApprox Mapp(PSurf,anApproxTol, MaxSeg,MaxDegree,dmax);
360     aSurf = Mapp.Surface();
361   }
362   else 
363     return;
364
365   ShapeAnalysis_FreeBounds aFreeBounds(aShape, Standard_False, Standard_True);
366   TopoDS_Compound aClosedWires = aFreeBounds.GetClosedWires();
367   TopTools_IndexedMapOfShape aWires;
368   TopExp::MapShapes(aClosedWires, TopAbs_WIRE, aWires);
369   TopoDS_Wire aWire;
370   Standard_Integer nbWires = aWires.Extent();
371   if (nbWires) 
372     aWire = TopoDS::Wire(aWires(1));
373   else 
374     return;
375
376   BRep_Builder B;
377   TopoDS_Face aFace;
378   B.MakeFace(aFace, aSurf, Precision::Confusion());
379   B.Add(aFace, aWire);
380   Handle_ShapeFix_Shape sfs = new ShapeFix_Shape(aFace);
381   sfs->Perform();
382   TopoDS_Shape aFixedFace = sfs->Shape();
383   if (aFixedFace.IsNull()) 
384     return;
385
386   // output surface, make it half transparent
387   Handle_AIS_InteractiveObject aSurfIO = drawSurface(
388     aSurf, Quantity_NOC_LEMONCHIFFON3, Standard_False);
389   aSurfIO->SetTransparency(0.5);
390   getAISContext()->Display(aSurfIO, Standard_False);
391   COCCDemoDoc::Fit();
392
393   if(WAIT_A_LITTLE) return;
394
395   // output points
396   for(i = 1; i <= nbNodes; i++)
397     drawPoint(aPoints(i));
398
399   if(WAIT_A_LITTLE) return;
400   
401   // output resulting face
402   drawShape(aFixedFace);
403 }
404
405
406
407 //================================================================
408 // Function : Simplify_Presentation::sample
409 // Purpose  : 
410 //================================================================
411 void Simplify_Presentation::sample(const Standard_CString aFileName)
412 {
413   TCollection_AsciiString aPath(GetDataDir());
414   aPath = aPath + "\\" + aFileName;
415
416   TopoDS_Shape aShape;
417   BRep_Builder aBld;
418   Standard_Boolean isRead = BRepTools::Read (aShape, aPath.ToCString(), aBld);
419   if (!isRead)
420   {
421     aPath += " was not found.  The sample can not be shown.";
422     setResultText(aPath.ToCString());
423     return;
424   }
425
426   simplify(aShape);
427 }