1 // Created on: 1995-01-03
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1995-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.
17 // pdn 30.11.98: fixes improved
18 // pdn 20.12.98: to keep pcurves
19 // pdn 28.12.98: PRO10366 shifting pcurve between two singularities
20 //:p4 abv, pdn 23.02.99: PRO9234 #15720: call BRepTools::Update() for faces
21 //:q7 abv 23.03.99: bm4_al_eye.stp #53710: remove pseudo-seams
22 // rln 31.03.99 S4135: prohibit fixing intersection of non-adjacent edges (temporarily)
23 //#4 szv S4163: optimization
24 //%19 pdn 17.04.99 using ShapeFix_Wire::FixEdgeCurves instead of ShapeFix_PCurves
25 // smh 31.01.01 Bad data in file : case of vertex loop on plane face
26 // sln 01.10.2001 BUC61003. StepToTopoDS_TranslateFace::Init function is corrected (verifying Handle(...).IsNull() is added)
28 #include <BRep_Builder.hxx>
29 #include <BRep_TEdge.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRep_TVertex.hxx>
32 #include <BRepBuilderAPI_MakeFace.hxx>
33 #include <BRepTools.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom_BoundedSurface.hxx>
36 #include <Geom_BSplineSurface.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_SphericalSurface.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_SurfaceOfRevolution.hxx>
41 #include <Geom_ToroidalSurface.hxx>
42 #include <GeomAbs_Shape.hxx>
43 #include <GeomAdaptor_Surface.hxx>
44 #include <Precision.hxx>
45 #include <ShapeAlgo.hxx>
46 #include <ShapeAlgo_AlgoContainer.hxx>
47 #include <StdFail_NotDone.hxx>
48 #include <StepGeom_BSplineSurface.hxx>
49 #include <StepGeom_BSplineSurfaceForm.hxx>
50 #include <StepGeom_OffsetSurface.hxx>
51 #include <StepGeom_Surface.hxx>
52 #include <StepShape_Edge.hxx>
53 #include <StepShape_EdgeCurve.hxx>
54 #include <StepShape_EdgeLoop.hxx>
55 #include <StepShape_FaceBound.hxx>
56 #include <StepShape_FaceOuterBound.hxx>
57 #include <StepShape_FaceSurface.hxx>
58 #include <StepShape_OrientedEdge.hxx>
59 #include <StepShape_PolyLoop.hxx>
60 #include <StepShape_VertexLoop.hxx>
61 #include <StepToGeom.hxx>
62 #include <StepToTopoDS.hxx>
63 #include <StepToTopoDS_NMTool.hxx>
64 #include <StepToTopoDS_Tool.hxx>
65 #include <StepToTopoDS_TranslateEdgeLoop.hxx>
66 #include <StepToTopoDS_TranslateFace.hxx>
67 #include <StepToTopoDS_TranslatePolyLoop.hxx>
68 #include <StepToTopoDS_TranslateVertexLoop.hxx>
69 #include <TCollection_HAsciiString.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
75 #include <TopoDS_Iterator.hxx>
76 #include <TopoDS_Shape.hxx>
77 #include <TopoDS_Vertex.hxx>
78 #include <TopoDS_Wire.hxx>
79 #include <Transfer_TransientProcess.hxx>
80 #include <StepGeom_RectangularTrimmedSurface.hxx>
81 #include <StepGeom_ToroidalSurface.hxx>
84 //#include <GeomAdaptor_Curve.hxx>
85 //#include <GeomAdaptor_CurveOnSurface.hxx>
89 // Provisoire, pour VertexLoop
91 // To proceed with I-DEAS-like STP (ssv; 15.11.2010)
93 // ============================================================================
94 // Method : StepToTopoDS_TranslateFace::StepToTopoDS_TranslateFace
95 // Purpose : Empty Constructor
96 // ============================================================================
97 StepToTopoDS_TranslateFace::StepToTopoDS_TranslateFace()
98 : myError(StepToTopoDS_TranslateFaceOther)
100 done = Standard_False;
103 // ============================================================================
104 // Method : StepToTopoDS_TranslateFace::StepToTopoDS_TranslateFace
105 // Purpose : Constructor with a FaceSurface and a Tool
106 // ============================================================================
108 StepToTopoDS_TranslateFace::StepToTopoDS_TranslateFace
109 (const Handle(StepShape_FaceSurface)& FS, StepToTopoDS_Tool& T, StepToTopoDS_NMTool& NMTool)
114 // ============================================================================
116 // Purpose : Init with a FaceSurface and a Tool
117 // ============================================================================
119 static inline Standard_Boolean isReversed(const Handle(StepGeom_Surface)& theStepSurf)
121 Handle(StepGeom_ToroidalSurface) aStepTorSur;
122 if(theStepSurf->IsKind(STANDARD_TYPE(StepGeom_RectangularTrimmedSurface)))
123 return isReversed(Handle(StepGeom_RectangularTrimmedSurface)::DownCast(theStepSurf)->BasisSurface());
126 aStepTorSur = Handle(StepGeom_ToroidalSurface)::DownCast(theStepSurf);
128 return (!aStepTorSur.IsNull() && aStepTorSur->MajorRadius() < 0 ? Standard_True : Standard_False);
131 // ============================================================================
133 // Purpose : Init with a FaceSurface and a Tool
134 // ============================================================================
136 void StepToTopoDS_TranslateFace::Init
137 (const Handle(StepShape_FaceSurface)& FS, StepToTopoDS_Tool& aTool, StepToTopoDS_NMTool& NMTool)
139 done = Standard_True;
140 if (aTool.IsBound(FS)) {
141 myResult = TopoDS::Face(aTool.Find(FS));
142 myError = StepToTopoDS_TranslateFaceDone;
143 done = Standard_True;
147 Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
149 // ----------------------------------------------
150 // Map the Face Geometry and create a TopoDS_Face
151 // ----------------------------------------------
153 Handle(StepGeom_Surface) StepSurf = FS->FaceGeometry();
155 // sln 01.10.2001 BUC61003. If corresponding entity was read with error StepSurface may be NULL. In this case we exit from function
156 if ( StepSurf.IsNull() ) {
157 TP->AddFail(StepSurf," Surface has not been created");
158 myError = StepToTopoDS_TranslateFaceOther;
159 done = Standard_False;
163 // [BEGIN] Added to process non-manifold topology (ssv; 14.11.2010)
164 if ( NMTool.IsActive() && NMTool.IsBound(StepSurf) ) {
165 TopoDS_Shape existingShape = NMTool.Find(StepSurf);
166 // Reverse shape's orientation for the next shell
167 existingShape.Reverse();
168 myResult = existingShape;
169 myError = StepToTopoDS_TranslateFaceDone;
170 done = Standard_True;
173 // [END] Added to process non-manifold topology (ssv; 14.11.2010)
175 if (StepSurf->IsKind(STANDARD_TYPE(StepGeom_OffsetSurface))) //:d4 abv 12 Mar 98
176 TP->AddWarning(StepSurf," Type OffsetSurface is out of scope of AP 214");
177 Handle(Geom_Surface) GeomSurf = StepToGeom::MakeSurface (StepSurf);
178 if (GeomSurf.IsNull())
180 TP->AddFail(StepSurf," Surface has not been created");
181 myError = StepToTopoDS_TranslateFaceOther;
182 done = Standard_False;
185 // pdn to force bsplsurf to be periodic
186 Handle(StepGeom_BSplineSurface) sgbss = Handle(StepGeom_BSplineSurface)::DownCast(StepSurf);
187 if (!sgbss.IsNull()) {
188 Handle(Geom_Surface) periodicSurf = ShapeAlgo::AlgoContainer()->ConvertToPeriodic(GeomSurf);
189 if (!periodicSurf.IsNull()) {
190 TP->AddWarning(StepSurf, "Surface forced to be periodic");
191 GeomSurf = periodicSurf;
195 Standard_Boolean sameSenseFace = FS->SameSense();
197 //fix for bug 0026376 Solid Works wrote face based on toroidal surface having negative major radius
198 //seems that such case is interpreted by "Solid Works" and "ProE" as face having reversed orientation.
199 Standard_Boolean sameSense = (isReversed(StepSurf) ? !sameSenseFace : sameSenseFace);
202 aTool.AddContinuity (GeomSurf);
206 B.MakeFace ( F, GeomSurf, Precision::Confusion() );
208 // ----------------------------------
209 // Iterate on each FaceBounds (Wires)
210 // ----------------------------------
212 Handle(StepShape_FaceBound) FaceBound;
213 Handle(StepShape_Loop) Loop;
215 StepToTopoDS_TranslateVertexLoop myTranVL;
216 StepToTopoDS_TranslatePolyLoop myTranPL;
217 StepToTopoDS_TranslateEdgeLoop myTranEdgeLoop;
219 Standard_Integer NbBnd = FS->NbBounds();
221 // -- Critere de couture simple (CKY, JAN97)
222 // surface periodique (typiquement un cylindre)
223 // 2 face bounds, chacun avec un edge loop d une seule edge
224 // cette edge est fermee, c-a-d vtx-deb = vtx-fin (pour les deux edges)
225 // est-ce suffisant (verifier que ce sont deux outer-bounds ... ?? comment ?)
226 // Alors on peut dire : face a deux bords dont la couture manque
227 // La couture est entre les deux vertex
229 for (Standard_Integer i = 1; i <= NbBnd; i ++) {
232 std::cout << " Processing Wire : " << i << std::endl;
234 FaceBound = FS->BoundsValue(i);
235 Loop = FaceBound->Bound();
237 // ------------------------
238 // The Loop is a VertexLoop
239 // ------------------------
241 if (Loop->IsKind(STANDARD_TYPE(StepShape_VertexLoop))) {
242 //:S4136 STF.Closed() = Standard_False;
243 // PROBLEME si SPHERE ou TORE
244 // Il faudra faire un wire complet, a condition que le point porte sur la face
245 // En attendant, on ne fait rien
246 Handle(StepShape_VertexLoop) VL = Handle(StepShape_VertexLoop)::DownCast(Loop);
248 // abv 10.07.00 pr1sy.stp: vertex_loop can be wrong; so just make natural bounds
249 if (GeomSurf->IsKind (STANDARD_TYPE(Geom_SphericalSurface)) ||
250 GeomSurf->IsKind (STANDARD_TYPE(Geom_BSplineSurface)) ||
251 GeomSurf->IsKind (STANDARD_TYPE(Geom_SurfaceOfRevolution)))
254 // Modification to create natural bounds for face based on the spherical and Bspline surface and having only one bound represented by Vertex loop was made.
255 // According to the specification of ISO - 10303 part 42:
256 // "If the face has only one bound and this is of type vertex_loop, then the interior of the face is the domain of the face_surface.face_geometry.
257 // In such a case the underlying surface shall be closed (e.g. a spherical_surface.)"
258 // - natural bounds are applied only in case if VertexLoop is only the one defined face bound.
260 BRepBuilderAPI_MakeFace mf(GeomSurf, Precision());
261 for (TopoDS_Iterator it(mf); it.More(); it.Next())
262 B.Add(F, it.Value());
269 if (GeomSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
272 if (GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
273 TP->AddWarning(VL, "VertexLoop on plane is ignored");
274 continue; //smh : BUC60809
276 myTranVL.SetPrecision(Precision());//gka
277 myTranVL.SetMaxTol(MaxTol());
278 myTranVL.Init(VL, aTool, NMTool);
279 if (myTranVL.IsDone()) {
280 B.Add(F, myTranVL.Value());
283 TP->AddWarning(VL, " a VertexLoop not mapped to TopoDS");
287 // ----------------------
288 // The Loop is a PolyLoop
289 // ----------------------
291 else if (Loop->IsKind(STANDARD_TYPE(StepShape_PolyLoop))) {
292 //:S4136 STF.Closed() = Standard_False;
293 Handle(StepShape_PolyLoop) PL = Handle(StepShape_PolyLoop)::DownCast(Loop);
294 F.Orientation ( FS->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
295 myTranPL.SetPrecision(Precision()); //gka
296 myTranPL.SetMaxTol(MaxTol());
297 myTranPL.Init(PL, aTool, GeomSurf, F);
298 if (myTranPL.IsDone()) {
299 TopoDS_Wire W = TopoDS::Wire(myTranPL.Value());
300 W.Orientation(FaceBound->Orientation() ? TopAbs_FORWARD : TopAbs_REVERSED);
304 TP->AddWarning(PL, " a PolyLoop not mapped to TopoDS");
308 // -----------------------
309 // The Loop is an EdgeLoop
310 // -----------------------
312 else if (Loop->IsKind(STANDARD_TYPE(StepShape_EdgeLoop))) {
313 //:S4136 if (STF.Closed()) {
314 //:S4136 Handle(StepShape_EdgeLoop) EL =
315 //:S4136 Handle(StepShape_EdgeLoop)::DownCast(FaceBound->Bound());
316 //:S4136 if (EL->NbEdgeList() != 1) STF.Closed() = Standard_False;
320 myTranEdgeLoop.SetPrecision(Precision()); //gka
321 myTranEdgeLoop.SetMaxTol(MaxTol());
322 myTranEdgeLoop.Init(FaceBound, F, GeomSurf, StepSurf, sameSense, aTool, NMTool);
324 if (myTranEdgeLoop.IsDone()) {
325 W = TopoDS::Wire(myTranEdgeLoop.Value());
327 // STEP Face_Surface orientation :
328 // if the topological orientation is opposite to the geometric
329 // orientation of the surface => the underlying topological
330 // orientation are not implicitly reversed
331 // this is the case in CAS.CADE => If the face_surface is reversed,
332 // the wire orientation has to be explictly reversed
333 if (FaceBound->Orientation()) {
334 // *DTH* if (sameSense || GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
335 W.Orientation(sameSense ? TopAbs_FORWARD : TopAbs_REVERSED);
338 // *DTH* if (sameSense || GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
339 W.Orientation(sameSense ? TopAbs_REVERSED : TopAbs_FORWARD);
341 // -----------------------------
342 // The Wire is added to the Face
343 // -----------------------------
348 // Il y a eu un probleme dans le mapping : On perd la Face
349 // (facon de parler ...) Pas de moyen aujourd hui de recuperer
350 // au moins toutes les geometries (Points, Courbes 3D, Surface)
351 TP->AddFail(Loop, " EdgeLoop not mapped to TopoDS");
353 // CKY JAN-97 : un Wire manque, eh bien on continue quand meme !!
354 // sauf si OuterBound : la c est quand meme pas bien normal ...
355 if (FaceBound->IsKind(STANDARD_TYPE(StepShape_FaceOuterBound))) {
356 TP->AddWarning(FS, "No Outer Bound : Face not done");
362 // Type not yet implemented or non sens
363 TP->AddFail(Loop," Type of loop not yet implemented");
365 std::cout << Loop->DynamicType() << std::endl;
371 F.Orientation ( FS->SameSense() ? TopAbs_FORWARD : TopAbs_REVERSED);
374 // Register face in NM tool (ssv; 14.11.2010)
375 if ( NMTool.IsActive() )
376 NMTool.Bind(StepSurf, F);
379 myError = StepToTopoDS_TranslateFaceDone;
380 done = Standard_True;
384 // ============================================================================
386 // Purpose : Return the mapped Shape
387 // ============================================================================
389 const TopoDS_Shape& StepToTopoDS_TranslateFace::Value() const
391 StdFail_NotDone_Raise_if (!done, "StepToTopoDS_TranslateFace::Value() - no result");
395 // ============================================================================
397 // Purpose : Return the TranslateFace error
398 // ============================================================================
400 StepToTopoDS_TranslateFaceError StepToTopoDS_TranslateFace::Error() const