0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_ShapeContents.cxx
1 // Created on: 1999-02-25
2 // Created by: Pavel DURANDIN
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //szv#4 S4163
18
19 #include <BRep_Tool.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom2d_OffsetCurve.hxx>
22 #include <Geom2d_TrimmedCurve.hxx>
23 #include <Geom_BezierSurface.hxx>
24 #include <Geom_BSplineSurface.hxx>
25 #include <Geom_Curve.hxx>
26 #include <Geom_ElementarySurface.hxx>
27 #include <Geom_OffsetCurve.hxx>
28 #include <Geom_OffsetSurface.hxx>
29 #include <Geom_RectangularTrimmedSurface.hxx>
30 #include <Geom_Surface.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <ShapeAnalysis_ShapeContents.hxx>
33 #include <ShapeAnalysis_Wire.hxx>
34 #include <ShapeExtend_WireData.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopoDS.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Shell.hxx>
40 #include <TopoDS_Solid.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Wire.hxx>
43 #include <TopTools_HSequenceOfShape.hxx>
44 #include <TopTools_MapOfShape.hxx>
45
46 ShapeAnalysis_ShapeContents::ShapeAnalysis_ShapeContents()
47 {
48   myBigSplineSec = new TopTools_HSequenceOfShape;
49   myIndirectSec = new TopTools_HSequenceOfShape;
50   myOffsetSurfaceSec = new TopTools_HSequenceOfShape;
51   myTrimmed3dSec = new TopTools_HSequenceOfShape;
52   myOffsetCurveSec = new TopTools_HSequenceOfShape;
53   myTrimmed2dSec = new TopTools_HSequenceOfShape;
54   ClearFlags();
55 }
56
57 void ShapeAnalysis_ShapeContents::Clear()
58 {
59   myNbSolids = 0;
60   myNbShells = 0;
61   myNbFaces = 0;
62   myNbWires = 0;
63   myNbEdges = 0;
64   myNbVertices = 0;
65   myNbSolidsWithVoids = 0;
66   myNbBigSplines = 0;
67   myNbC0Surfaces = 0;
68   myNbC0Curves = 0;
69   myNbOffsetSurf = 0;
70   myNbIndirectSurf = 0;
71   myNbOffsetCurves = 0;
72   myNbTrimmedCurve2d = 0;
73   myNbTrimmedCurve3d  =0;
74   myNbBSplibeSurf = 0;
75   myNbBezierSurf = 0;
76   myNbTrimSurf = 0;
77   myNbWireWitnSeam = 0;
78   myNbWireWithSevSeams = 0;
79   myNbFaceWithSevWires = 0;
80   myNbNoPCurve = 0;
81   myNbFreeFaces = 0;
82   myNbFreeWires = 0;
83   myNbFreeEdges = 0;
84   
85   myNbSharedSolids = 0;
86   myNbSharedShells = 0;
87   myNbSharedFaces = 0;
88   myNbSharedWires = 0;
89   myNbSharedFreeWires = 0;
90   myNbSharedFreeEdges = 0;
91   myNbSharedEdges = 0;
92   myNbSharedVertices = 0;
93     
94   myBigSplineSec->Clear();
95   myIndirectSec->Clear();
96   myOffsetSurfaceSec->Clear();
97   myTrimmed3dSec->Clear();
98   myOffsetCurveSec->Clear();
99   myTrimmed2dSec->Clear();
100 }
101
102
103 void ShapeAnalysis_ShapeContents::ClearFlags()
104 {
105   myBigSplineMode = Standard_False;
106   myIndirectMode = Standard_False;
107   myOffestSurfaceMode = Standard_False;
108   myTrimmed3dMode = Standard_False;
109   myOffsetCurveMode = Standard_False;
110   myTrimmed2dMode = Standard_False;
111 }
112
113
114 void ShapeAnalysis_ShapeContents::Perform(const TopoDS_Shape& Shape)
115 {
116   Clear();
117   //  On y va
118   TopExp_Explorer exp;
119   TopTools_MapOfShape mapsh;
120 //  On note pour les SOLIDES : ceux qui ont des trous (plus d un SHELL)
121   
122   for (exp.Init (Shape,TopAbs_SOLID); exp.More(); exp.Next()) {
123     TopoDS_Solid sol = TopoDS::Solid (exp.Current());
124     sol.Location(TopLoc_Location());
125     mapsh.Add(sol);
126     Standard_Integer nbs = 0;
127     for (TopExp_Explorer shel (sol,TopAbs_SHELL); shel.More(); shel.Next())
128       nbs ++;
129     if (nbs > 1) myNbSolidsWithVoids++;
130     myNbSolids++;  
131   }
132   myNbSharedSolids = mapsh.Extent();
133
134 //  Pour les SHELLS, on compte les faces dans les SHELLS
135 //  Ensuite une soustraction, et on a les faces libres
136   mapsh.Clear();
137   Standard_Integer nbfaceshell = 0;
138   for (exp.Init (Shape,TopAbs_SHELL); exp.More(); exp.Next()) {
139     myNbShells++;
140     TopoDS_Shell she = TopoDS::Shell(exp.Current());
141     she.Location(TopLoc_Location());
142     mapsh.Add(she);
143     for (TopExp_Explorer shel (she,TopAbs_FACE); shel.More(); shel.Next())
144       nbfaceshell ++;
145   }
146   myNbSharedShells = mapsh.Extent();
147 //  On note pour les FACES pas mal de choses (surface, topologie)
148 //  * Surface BSpline > 8192 poles
149 //  * Surface BSpline "OnlyC0" (not yet impl)
150 //  * Surface Offset
151 //  * Surface Elementaire INDIRECTE
152 //  * Presence de COUTURES; en particulier WIRE A PLUS D UNE COUTURE
153 //  * Edge : OffsetCurve
154
155   mapsh.Clear();
156   for (exp.Init (Shape,TopAbs_FACE); exp.More(); exp.Next()) {
157     TopoDS_Face face = TopoDS::Face(exp.Current());
158     myNbFaces++;
159     TopLoc_Location loc;
160     Handle(Geom_Surface) surf = BRep_Tool::Surface (face,loc);
161     face.Location(TopLoc_Location());
162     mapsh.Add(face);
163     Handle(Geom_RectangularTrimmedSurface) trsu =
164       Handle(Geom_RectangularTrimmedSurface)::DownCast (surf);
165     if (!trsu.IsNull()) {
166       myNbTrimSurf++;
167       surf = trsu->BasisSurface();
168     }
169     //#10 rln 27/02/98 BUC50003 entity 56
170     //C0 if at least in one direction (U or V)
171     if (!surf.IsNull() && !(surf->IsCNu(1) && surf->IsCNv(1))) {
172       myNbC0Surfaces++;
173     }
174
175     Handle(Geom_BSplineSurface) bsps = Handle(Geom_BSplineSurface)::DownCast(surf);
176     if (!bsps.IsNull()) {
177       myNbBSplibeSurf++;
178       if (bsps->NbUPoles() * bsps->NbVPoles() > 8192) {
179         myNbBigSplines++;
180         if (myBigSplineMode) myBigSplineSec->Append(face);
181       }
182     }
183     Handle(Geom_ElementarySurface) els = Handle(Geom_ElementarySurface)::DownCast(surf);
184     if (!els.IsNull()) {
185       if (!els->Position().Direct()) {
186         myNbIndirectSurf++;
187         if (myIndirectMode) myIndirectSec->Append(face);
188       }
189     }
190     if (surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
191       myNbOffsetSurf++;
192       if (myOffestSurfaceMode) myOffsetSurfaceSec->Append(face);
193     }
194     else if (surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
195       myNbBezierSurf++;
196     }
197
198     Standard_Integer maxseam = 0, nbwires = 0;
199     for (TopExp_Explorer wires(face,TopAbs_WIRE); wires.More(); wires.Next()) {
200       TopoDS_Wire wire = TopoDS::Wire (wires.Current());
201       Standard_Integer nbseam = 0;
202       nbwires ++;
203       for (TopExp_Explorer edg(wire,TopAbs_EDGE); edg.More(); edg.Next()) {
204         TopoDS_Edge edge = TopoDS::Edge (edg.Current());
205         Standard_Real first,last;       
206         if (BRep_Tool::IsClosed (edge,face)) nbseam ++;
207         Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,first,last);
208         if (!c3d.IsNull()) {
209           if (c3d->IsKind (STANDARD_TYPE(Geom_TrimmedCurve))) {
210             myNbTrimmedCurve3d++;
211             if (myTrimmed3dMode) myTrimmed3dSec->Append(face);
212           }
213         }
214         Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge,face,first,last);
215         if (c2d.IsNull()) myNbNoPCurve++;
216         else if (c2d->IsKind (STANDARD_TYPE(Geom2d_OffsetCurve))) {
217           myNbOffsetCurves++;
218           if (myOffsetCurveMode) myOffsetCurveSec->Append(face);
219         }
220         else if (c2d->IsKind (STANDARD_TYPE(Geom2d_TrimmedCurve))) {
221           myNbTrimmedCurve2d++;
222           if (myTrimmed2dMode) myTrimmed2dSec->Append(face);
223         }
224       }
225       if (nbseam > maxseam) maxseam = nbseam;
226     }
227     if (maxseam == 1) myNbWireWitnSeam++;
228     else if (maxseam > 1)
229       myNbWireWithSevSeams++;
230     if (nbwires > 1) myNbFaceWithSevWires++;
231   }
232   myNbSharedFaces = mapsh.Extent();
233   
234   mapsh.Clear();
235   for (exp.Init (Shape,TopAbs_WIRE); exp.More(); exp.Next()) {
236     TopoDS_Wire wire = TopoDS::Wire(exp.Current());
237     wire.Location(TopLoc_Location());
238     mapsh.Add(wire);
239     myNbWires++;
240   }
241   myNbSharedWires = mapsh.Extent();
242     
243 //  Ne pas oublier les FACES :
244   myNbFreeFaces = myNbFaces - nbfaceshell;
245
246   mapsh.Clear();
247   for (exp.Init (Shape,TopAbs_EDGE); exp.More(); exp.Next()) {
248     TopoDS_Edge edge = TopoDS::Edge (exp.Current());
249     edge.Location(TopLoc_Location());
250     mapsh.Add (edge);
251     TopLoc_Location loc;
252     Standard_Real first,last;
253     myNbEdges++;
254     Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,loc,first,last);
255     if (!c3d.IsNull() && c3d->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
256       myNbOffsetCurves++;
257       if (myOffsetCurveMode) myOffsetCurveSec->Append(edge);
258     }
259     if (!c3d.IsNull() && !c3d->IsCN(1)) myNbC0Curves++;
260   }
261   myNbSharedEdges=mapsh.Extent();
262
263   mapsh.Clear();
264   for (exp.Init (Shape,TopAbs_VERTEX); exp.More(); exp.Next()) {
265     TopoDS_Vertex vert = TopoDS::Vertex(exp.Current());
266     vert.Location(TopLoc_Location());
267     myNbVertices++;
268     mapsh.Add (vert);
269   }
270   myNbSharedVertices=mapsh.Extent();
271   
272   mapsh.Clear();
273   for (exp.Init(Shape, TopAbs_EDGE, TopAbs_FACE); exp.More(); exp.Next()) {
274     TopoDS_Edge edge = TopoDS::Edge (exp.Current());
275     edge.Location(TopLoc_Location());
276     myNbFreeEdges++;
277     mapsh.Add (edge);
278   }
279   myNbSharedFreeEdges=mapsh.Extent();
280   
281   mapsh.Clear();
282   for (exp.Init(Shape, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) {
283     TopoDS_Wire wire = TopoDS::Wire(exp.Current());
284     wire.Location(TopLoc_Location());
285     myNbFreeWires++;
286     mapsh.Add (wire);
287   }
288   myNbSharedFreeWires=mapsh.Extent();
289 }