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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
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>
46 ShapeAnalysis_ShapeContents::ShapeAnalysis_ShapeContents()
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;
57 void ShapeAnalysis_ShapeContents::Clear()
65 myNbSolidsWithVoids = 0;
72 myNbTrimmedCurve2d = 0;
73 myNbTrimmedCurve3d =0;
78 myNbWireWithSevSeams = 0;
79 myNbFaceWithSevWires = 0;
89 myNbSharedFreeWires = 0;
90 myNbSharedFreeEdges = 0;
92 myNbSharedVertices = 0;
94 myBigSplineSec->Clear();
95 myIndirectSec->Clear();
96 myOffsetSurfaceSec->Clear();
97 myTrimmed3dSec->Clear();
98 myOffsetCurveSec->Clear();
99 myTrimmed2dSec->Clear();
103 void ShapeAnalysis_ShapeContents::ClearFlags()
105 myBigSplineMode = Standard_False;
106 myIndirectMode = Standard_False;
107 myOffestSurfaceMode = Standard_False;
108 myTrimmed3dMode = Standard_False;
109 myOffsetCurveMode = Standard_False;
110 myTrimmed2dMode = Standard_False;
114 void ShapeAnalysis_ShapeContents::Perform(const TopoDS_Shape& Shape)
119 TopTools_MapOfShape mapsh;
120 // On note pour les SOLIDES : ceux qui ont des trous (plus d un SHELL)
122 for (exp.Init (Shape,TopAbs_SOLID); exp.More(); exp.Next()) {
123 TopoDS_Solid sol = TopoDS::Solid (exp.Current());
124 sol.Location(TopLoc_Location());
126 Standard_Integer nbs = 0;
127 for (TopExp_Explorer shel (sol,TopAbs_SHELL); shel.More(); shel.Next())
129 if (nbs > 1) myNbSolidsWithVoids++;
132 myNbSharedSolids = mapsh.Extent();
134 // Pour les SHELLS, on compte les faces dans les SHELLS
135 // Ensuite une soustraction, et on a les faces libres
137 Standard_Integer nbfaceshell = 0;
138 for (exp.Init (Shape,TopAbs_SHELL); exp.More(); exp.Next()) {
140 TopoDS_Shell she = TopoDS::Shell(exp.Current());
141 she.Location(TopLoc_Location());
143 for (TopExp_Explorer shel (she,TopAbs_FACE); shel.More(); shel.Next())
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)
151 // * Surface Elementaire INDIRECTE
152 // * Presence de COUTURES; en particulier WIRE A PLUS D UNE COUTURE
153 // * Edge : OffsetCurve
156 for (exp.Init (Shape,TopAbs_FACE); exp.More(); exp.Next()) {
157 TopoDS_Face face = TopoDS::Face(exp.Current());
160 Handle(Geom_Surface) surf = BRep_Tool::Surface (face,loc);
161 face.Location(TopLoc_Location());
163 Handle(Geom_RectangularTrimmedSurface) trsu =
164 Handle(Geom_RectangularTrimmedSurface)::DownCast (surf);
165 if (!trsu.IsNull()) {
167 surf = trsu->BasisSurface();
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))) {
175 Handle(Geom_BSplineSurface) bsps = Handle(Geom_BSplineSurface)::DownCast(surf);
176 if (!bsps.IsNull()) {
178 if (bsps->NbUPoles() * bsps->NbVPoles() > 8192) {
180 if (myBigSplineMode) myBigSplineSec->Append(face);
183 Handle(Geom_ElementarySurface) els = Handle(Geom_ElementarySurface)::DownCast(surf);
185 if (!els->Position().Direct()) {
187 if (myIndirectMode) myIndirectSec->Append(face);
190 if (surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
192 if (myOffestSurfaceMode) myOffsetSurfaceSec->Append(face);
194 else if (surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
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;
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);
209 if (c3d->IsKind (STANDARD_TYPE(Geom_TrimmedCurve))) {
210 myNbTrimmedCurve3d++;
211 if (myTrimmed3dMode) myTrimmed3dSec->Append(face);
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))) {
218 if (myOffsetCurveMode) myOffsetCurveSec->Append(face);
220 else if (c2d->IsKind (STANDARD_TYPE(Geom2d_TrimmedCurve))) {
221 myNbTrimmedCurve2d++;
222 if (myTrimmed2dMode) myTrimmed2dSec->Append(face);
225 if (nbseam > maxseam) maxseam = nbseam;
227 if (maxseam == 1) myNbWireWitnSeam++;
228 else if (maxseam > 1)
229 myNbWireWithSevSeams++;
230 if (nbwires > 1) myNbFaceWithSevWires++;
232 myNbSharedFaces = mapsh.Extent();
235 for (exp.Init (Shape,TopAbs_WIRE); exp.More(); exp.Next()) {
236 TopoDS_Wire wire = TopoDS::Wire(exp.Current());
237 wire.Location(TopLoc_Location());
241 myNbSharedWires = mapsh.Extent();
243 // Ne pas oublier les FACES :
244 myNbFreeFaces = myNbFaces - nbfaceshell;
247 for (exp.Init (Shape,TopAbs_EDGE); exp.More(); exp.Next()) {
248 TopoDS_Edge edge = TopoDS::Edge (exp.Current());
249 edge.Location(TopLoc_Location());
252 Standard_Real first,last;
254 Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,loc,first,last);
255 if (!c3d.IsNull() && c3d->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
257 if (myOffsetCurveMode) myOffsetCurveSec->Append(edge);
259 if (!c3d.IsNull() && !c3d->IsCN(1)) myNbC0Curves++;
261 myNbSharedEdges=mapsh.Extent();
264 for (exp.Init (Shape,TopAbs_VERTEX); exp.More(); exp.Next()) {
265 TopoDS_Vertex vert = TopoDS::Vertex(exp.Current());
266 vert.Location(TopLoc_Location());
270 myNbSharedVertices=mapsh.Extent();
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());
279 myNbSharedFreeEdges=mapsh.Extent();
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());
288 myNbSharedFreeWires=mapsh.Extent();