Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-03-29 |
2 | // Created by: Frederic MAUPAS | |
3 | // Copyright (c) 1995-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
b311480e | 16 | |
7fd59977 | 17 | // gka 21.08.98 PRO7656 |
18 | // gka 15.12.98 UKI60591 #1274560 | |
19 | //pdn 18.12.98 to keep pcurves | |
20 | //:o0 abv 16.02.99: POLYLINE allowed as 3d curve of edge | |
21 | //: abv 07.04.99: S4136: improve tolerance management and dealing with pcurves | |
22 | // rln 02.06.99 removing #include <StepToTopoDS_DegeneratedTool.hxx> | |
23 | // smh 31.01.01 BUC60810 : IsNull protection | |
7fd59977 | 24 | |
25 | #include <BRep_Builder.hxx> | |
7fd59977 | 26 | #include <BRep_CurveRepresentation.hxx> |
7fd59977 | 27 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
42cf5bc1 | 28 | #include <BRep_ListOfCurveRepresentation.hxx> |
29 | #include <BRep_TEdge.hxx> | |
30 | #include <BRep_Tool.hxx> | |
31 | #include <ElCLib.hxx> | |
7fd59977 | 32 | #include <Geom2d_BoundedCurve.hxx> |
42cf5bc1 | 33 | #include <Geom2d_Curve.hxx> |
7fd59977 | 34 | #include <Geom2d_Line.hxx> |
42cf5bc1 | 35 | #include <Geom_Curve.hxx> |
36 | #include <Geom_Plane.hxx> | |
37 | #include <Geom_RectangularTrimmedSurface.hxx> | |
38 | #include <Geom_Surface.hxx> | |
7fd59977 | 39 | #include <gp_Pnt.hxx> |
40 | #include <gp_Pnt2d.hxx> | |
7fd59977 | 41 | #include <Interface_Static.hxx> |
42cf5bc1 | 42 | #include <Precision.hxx> |
7fd59977 | 43 | #include <ShapeAlgo.hxx> |
44 | #include <ShapeAlgo_AlgoContainer.hxx> | |
45 | #include <ShapeAlgo_ToolContainer.hxx> | |
42cf5bc1 | 46 | #include <ShapeAnalysis_Curve.hxx> |
47 | #include <ShapeAnalysis_Edge.hxx> | |
48 | #include <ShapeBuild_Edge.hxx> | |
49 | #include <ShapeExtend_WireData.hxx> | |
50 | #include <ShapeFix_EdgeProjAux.hxx> | |
d088c9c2 | 51 | #include <Standard_ErrorHandler.hxx> |
42cf5bc1 | 52 | #include <StdFail_NotDone.hxx> |
53 | #include <StepGeom_Curve.hxx> | |
54 | #include <StepGeom_Pcurve.hxx> | |
55 | #include <StepGeom_PcurveOrSurface.hxx> | |
ec357c5c | 56 | #include <StepGeom_Polyline.hxx> |
42cf5bc1 | 57 | #include <StepGeom_Surface.hxx> |
58 | #include <StepGeom_SurfaceCurve.hxx> | |
59 | #include <StepRepr_DefinitionalRepresentation.hxx> | |
60 | #include <StepShape_Edge.hxx> | |
61 | #include <StepShape_EdgeCurve.hxx> | |
62 | #include <StepShape_EdgeLoop.hxx> | |
63 | #include <StepShape_FaceBound.hxx> | |
64 | #include <StepShape_OrientedEdge.hxx> | |
65 | #include <StepShape_Vertex.hxx> | |
caaeed1b | 66 | #include <StepToGeom.hxx> |
42cf5bc1 | 67 | #include <StepToTopoDS.hxx> |
68 | #include <StepToTopoDS_GeometricTool.hxx> | |
69 | #include <StepToTopoDS_NMTool.hxx> | |
70 | #include <StepToTopoDS_Tool.hxx> | |
71 | #include <StepToTopoDS_TranslateEdge.hxx> | |
72 | #include <StepToTopoDS_TranslateEdgeLoop.hxx> | |
73 | #include <StepToTopoDS_TranslateVertex.hxx> | |
74 | #include <TopAbs.hxx> | |
75 | #include <TopExp.hxx> | |
76 | #include <TopExp_Explorer.hxx> | |
77 | #include <TopLoc_Location.hxx> | |
78 | #include <TopoDS.hxx> | |
79 | #include <TopoDS_Edge.hxx> | |
80 | #include <TopoDS_Face.hxx> | |
81 | #include <TopoDS_Iterator.hxx> | |
82 | #include <TopoDS_Shape.hxx> | |
83 | #include <TopoDS_Vertex.hxx> | |
84 | #include <TopoDS_Wire.hxx> | |
85 | #include <Transfer_TransientProcess.hxx> | |
86 | #include <XSAlgo.hxx> | |
87 | #include <XSAlgo_AlgoContainer.hxx> | |
7fd59977 | 88 | |
89 | // ============================================================================ | |
90 | // Method : RemoveSinglePCurve | |
91 | // Purpose : | |
92 | // ============================================================================ | |
7fd59977 | 93 | static void RemoveSinglePCurve (const TopoDS_Edge& aEdge, const TopoDS_Face& aFace) |
94 | { | |
95 | ShapeBuild_Edge().RemovePCurve (aEdge, aFace); | |
96 | } | |
97 | ||
98 | // ============================================================================ | |
99 | // Method : RemovePCurves | |
100 | // Purpose : | |
101 | // ============================================================================ | |
102 | ||
103 | static void RemovePCurves(const TopoDS_Wire& aWire, const TopoDS_Face& aFace) | |
104 | { | |
105 | TopExp_Explorer EdgeExp(aWire, TopAbs_EDGE); | |
106 | while (EdgeExp.More()) { | |
107 | const TopoDS_Edge& myEdge = TopoDS::Edge(EdgeExp.Current()); | |
a90dd15e | 108 | RemoveSinglePCurve(myEdge, aFace); |
7fd59977 | 109 | EdgeExp.Next(); |
110 | } | |
111 | } | |
112 | ||
113 | // ============================================================================ | |
114 | // Method : CheckPCurves | |
115 | // Purpose : Checks the pcurves topological trimming parameter consistency | |
116 | // and deviation between 2D ans 3D | |
117 | // ============================================================================ | |
118 | ||
119 | static void CheckPCurves (TopoDS_Wire& aWire, const TopoDS_Face& aFace, | |
a90dd15e | 120 | const Standard_Boolean isPlane, const Standard_Real preci) |
7fd59977 | 121 | { |
a90dd15e | 122 | if (isPlane) { RemovePCurves (aWire, aFace);return; } |
7fd59977 | 123 | BRep_Builder B; |
124 | Standard_Real w1, w2, cf, cl; | |
125 | Handle(Geom_Surface) mySurf = BRep_Tool::Surface(aFace); | |
a90dd15e | 126 | |
127 | Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData (aWire); | |
7fd59977 | 128 | for (Standard_Integer i = 1; i <= sbwd->NbEdges(); i++) { |
129 | const TopoDS_Edge& myEdge = sbwd->Edge(i); | |
a90dd15e | 130 | |
7fd59977 | 131 | // First Check : 2D Parameters on Edge : |
132 | // Case 1 : w1 == w2 illegal => Drop the PCurve | |
133 | // Case 2 : on bounded curve w1 < FirstParameter => w1 = FirstParameter | |
134 | // w2 > LastParameter => w2 = LastParameter | |
135 | ||
136 | Handle(Geom2d_Curve) thePC; | |
137 | ShapeAnalysis_Edge sae; | |
a90dd15e | 138 | if (!sae.PCurve (myEdge, aFace, thePC, w1, w2, Standard_False)) { |
7fd59977 | 139 | continue; |
140 | } | |
141 | cf = thePC->FirstParameter(); | |
142 | cl = thePC->LastParameter(); | |
a90dd15e | 143 | |
7fd59977 | 144 | if (w1 == w2) { |
a90dd15e | 145 | RemoveSinglePCurve(myEdge, aFace); |
0797d9d3 | 146 | #ifdef OCCT_DEBUG |
04232180 | 147 | std::cout<<"Removing pcuve w1=w2"<<std::endl; |
7fd59977 | 148 | #endif |
149 | continue; | |
150 | } | |
151 | ||
a90dd15e | 152 | //check parameters of range only for not periodic curves |
153 | if (!thePC->IsPeriodic()) | |
154 | { | |
155 | if (w1 < cf) { | |
156 | B.Range(myEdge, aFace, cf, w2); | |
157 | w1 = cf; | |
158 | } | |
159 | if (w2 > cl) { | |
160 | B.Range(myEdge, aFace, w1, cl); | |
161 | w2 = cl; | |
162 | } | |
7fd59977 | 163 | } |
bcf045cf | 164 | |
165 | if (w1 > w2 && mySurf->IsUPeriodic()) | |
166 | { | |
a90dd15e | 167 | Standard_Real u1, u2, v1, v2; |
168 | mySurf->Bounds(u1, u2, v1, v2); | |
169 | ElCLib::AdjustPeriodic(u1, u2, | |
170 | Min(Abs(w2-w1)/2, Precision::PConfusion()), | |
bcf045cf | 171 | w1, w2); |
a90dd15e | 172 | B.Range(myEdge, aFace, w1, w2); |
bcf045cf | 173 | } |
174 | ||
a90dd15e | 175 | |
7fd59977 | 176 | // advanced check |
a90dd15e | 177 | XSAlgo::AlgoContainer()->CheckPCurve (myEdge, aFace, preci, sbwd->IsSeam(i)); |
7fd59977 | 178 | } |
179 | } | |
180 | ||
181 | // ============================================================================ | |
182 | // Method : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop | |
183 | // Purpose : Empty Constructor | |
184 | // ============================================================================ | |
185 | ||
186 | StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop() | |
187 | { | |
188 | done = Standard_False; | |
189 | } | |
190 | ||
191 | // ============================================================================ | |
192 | // Method : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop | |
193 | // Purpose : Constructor with a FaceSurface and a Tool | |
194 | // ============================================================================ | |
195 | ||
a90dd15e | 196 | StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop(const Handle(StepShape_FaceBound)& FB, |
197 | const TopoDS_Face& Face, | |
198 | const Handle(Geom_Surface)& GeomSurf, | |
199 | const Handle(StepGeom_Surface)& StepSurf, | |
200 | const Standard_Boolean sameSense, | |
201 | StepToTopoDS_Tool& T, | |
202 | StepToTopoDS_NMTool& NMTool) { | |
7fd59977 | 203 | Init(FB, Face, GeomSurf, StepSurf, sameSense, T, NMTool); |
204 | } | |
205 | ||
206 | // ============================================================================ | |
207 | // Method : Init | |
208 | // Purpose : Init with a EdgeLoop and a Tool | |
209 | // ============================================================================ | |
210 | ||
a90dd15e | 211 | void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& FaceBound, |
212 | const TopoDS_Face& Face, | |
213 | const Handle(Geom_Surface)& GeomSurf, | |
214 | const Handle(StepGeom_Surface)& StepSurf, | |
215 | const Standard_Boolean sameSense, | |
216 | StepToTopoDS_Tool& aTool, | |
217 | StepToTopoDS_NMTool& NMTool) { | |
7fd59977 | 218 | done = Standard_True; |
a90dd15e | 219 | Handle(StepShape_EdgeLoop) EL = |
7fd59977 | 220 | Handle(StepShape_EdgeLoop)::DownCast(FaceBound->Bound()); |
221 | ||
222 | if (aTool.IsBound(EL)) { | |
223 | myResult = TopoDS::Wire(aTool.Find(EL)); | |
224 | myError = StepToTopoDS_TranslateEdgeLoopDone; | |
225 | done = Standard_True; | |
226 | return; | |
227 | } | |
228 | Standard_Integer modepcurve = Interface_Static::IVal("read.surfacecurve.mode"); | |
a90dd15e | 229 | // 0,1 : suivre le code, 2 : ne prendre que pcurve, 3 : ne prendre que C3D |
7fd59977 | 230 | |
231 | BRep_Builder B; | |
232 | Handle(Transfer_TransientProcess) TP = aTool.TransientProcess(); | |
a90dd15e | 233 | |
7fd59977 | 234 | Standard_Real preci = Precision(); |
235 | TopoDS_Wire W; | |
236 | TopoDS_Edge E; | |
237 | TopoDS_Vertex V; | |
238 | ||
7fd59977 | 239 | Standard_Boolean isSeam, isLikeSeam; |
a90dd15e | 240 | |
7fd59977 | 241 | Handle(StepShape_OrientedEdge) OrEdge1, OrEdge2; |
242 | Handle(StepGeom_Curve) StepCurve, StepCurve1, StepCurve2; | |
7fd59977 | 243 | Handle(StepRepr_DefinitionalRepresentation) DRI, Dri1, Dri2; |
a90dd15e | 244 | |
7fd59977 | 245 | Handle(Geom2d_Curve) C2d, C2d1, C2d2, WhichC2d1, WhichC2d2; |
7fd59977 | 246 | TopoDS_Edge suspectE; //:f1, degEdge; |
a90dd15e | 247 | |
7fd59977 | 248 | Standard_Integer j, NbEdge = EL->NbEdgeList(); |
a90dd15e | 249 | if (NbEdge == 0) { |
250 | TP->AddWarning(EL, "Wire not done. EdgeLoop does not contain edges."); | |
7fd59977 | 251 | done = Standard_False; |
252 | return; | |
253 | } | |
a90dd15e | 254 | // PTV 16.09.2000 |
255 | // default value set as Standard_True (if not correct see logic of algorithm). | |
7fd59977 | 256 | Standard_Boolean hasPcurve = Standard_True; |
257 | Standard_Boolean isPlane = GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)); | |
258 | Handle(Geom_Surface) ConvSurf = GeomSurf; | |
259 | if (GeomSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { | |
260 | Handle(Geom_RectangularTrimmedSurface) theRTS = | |
261 | Handle(Geom_RectangularTrimmedSurface)::DownCast(GeomSurf); | |
262 | ConvSurf = theRTS->BasisSurface(); | |
263 | } | |
264 | ||
265 | aTool.ComputePCurve(Standard_False); | |
a90dd15e | 266 | |
7fd59977 | 267 | // What is the Wire Orientation |
268 | Standard_Boolean ForwardWire = FaceBound->Orientation(); | |
269 | ||
270 | // --- Initialize target Wire --- | |
271 | ||
272 | B.MakeWire(W); | |
273 | ||
7fd59977 | 274 | // ----------------------------------------------- |
275 | // Preparation : Make Vertices + Curves3d | |
276 | // Hence, a closed curve limited by distinct vertices | |
277 | // will give a unique vertex (if same coords) | |
278 | // | |
279 | // In addition : detect shared PCurve (cf SYRKO) | |
280 | // This case may not be processed, PCurves has to be recomputed from scratch | |
281 | // ----------------------------------------------- | |
282 | // Standard_Integer theSame = 1; //gka 15.12.98 | |
a90dd15e | 283 | |
284 | for (j=1; j<=NbEdge; j++) { | |
7fd59977 | 285 | OrEdge1 = EL->EdgeListValue(j); |
fa68c1e1 | 286 | |
287 | // see bug #29979: oriented edge contains another oriented edge | |
288 | if (OrEdge1->EdgeElement()->IsKind (STANDARD_TYPE(StepShape_OrientedEdge))) | |
289 | OrEdge1 = Handle(StepShape_OrientedEdge)::DownCast (OrEdge1->EdgeElement()); | |
290 | ||
291 | Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(OrEdge1->EdgeElement()); | |
292 | if (EC.IsNull()) | |
293 | { | |
294 | TP->AddWarning (OrEdge1, "Edge does not contain EDGE_CURVE, skipped"); | |
295 | continue; | |
296 | } | |
297 | ||
7fd59977 | 298 | Handle(StepGeom_Curve) C = EC->EdgeGeometry(); |
a90dd15e | 299 | if (!C.IsNull()) { |
2a141d40 | 300 | if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) { |
301 | Handle(StepGeom_SurfaceCurve) Sc = Handle(StepGeom_SurfaceCurve)::DownCast(C); | |
302 | C = Sc->Curve3d(); | |
2a141d40 | 303 | } |
7fd59977 | 304 | } |
7fd59977 | 305 | Handle(Geom_Curve) C1; |
306 | if (!C.IsNull()) { | |
d088c9c2 | 307 | try |
308 | { | |
309 | OCC_CATCH_SIGNALS | |
a90dd15e | 310 | C1 = Handle(Geom_Curve)::DownCast (TP->FindTransient(C)); |
d088c9c2 | 311 | if (C1.IsNull()) { |
caaeed1b | 312 | C1 = StepToGeom::MakeCurve (C); |
313 | if (! C1.IsNull()) | |
a90dd15e | 314 | TP->BindTransient (C, C1); |
d088c9c2 | 315 | else |
a90dd15e | 316 | TP->AddWarning(C, "Could not convert a curve. Curve definition is incorrect"); |
d088c9c2 | 317 | } |
318 | } | |
9775fa61 | 319 | catch (Standard_Failure const& anException) { |
d088c9c2 | 320 | #ifdef OCCT_DEBUG |
04232180 | 321 | std::cout << "Warning: StepToTopoDS_TranslateEdgeLoop: Exception: "; |
322 | anException.Print(std::cout); std::cout << std::endl; | |
d088c9c2 | 323 | #endif |
9775fa61 | 324 | (void)anException; |
a90dd15e | 325 | TP->AddFail(C, "Exeption was raised. Curve geometry definition is incorrect"); |
7fd59977 | 326 | } |
327 | } | |
328 | ||
329 | Handle(StepShape_Vertex) Vstart, Vend; | |
330 | if (EC->SameSense()) { | |
331 | Vstart = EC->EdgeStart(); | |
332 | Vend = EC->EdgeEnd(); | |
333 | } | |
334 | else { | |
335 | Vend = EC->EdgeStart(); | |
336 | Vstart = EC->EdgeEnd(); | |
337 | } | |
338 | ||
339 | Standard_Boolean istV = aTool.IsBound(Vstart); | |
340 | Standard_Boolean iseV = aTool.IsBound(Vend); | |
341 | TopoDS_Vertex V1, V2; | |
342 | StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool); | |
343 | StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool); | |
344 | ||
345 | if (myTranVertex1.IsDone()) { | |
346 | V1 = TopoDS::Vertex(myTranVertex1.Value()); | |
347 | } | |
7fd59977 | 348 | if (myTranVertex2.IsDone()) { |
349 | V2 = TopoDS::Vertex(myTranVertex2.Value()); | |
350 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
351 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
a90dd15e | 352 | if (p1.Distance(p2) <= Precision::Confusion()) { //:S4136: preci) { |
353 | Standard_Boolean Fixed = Standard_True; | |
354 | if (!iseV) aTool.Bind(Vend, V1); //gka 21.08.1998 bug PRO7656 | |
355 | else if (!istV) aTool.Bind (Vstart, V2); | |
356 | else aTool.Bind (Vend, V1); | |
357 | if (!C1.IsNull() && !C1->IsClosed() && Fixed) | |
358 | TP->AddWarning(EL->EdgeListValue(j), | |
359 | "Vertex of same coordinates, set confused"); | |
7fd59977 | 360 | } |
361 | } | |
362 | } | |
7fd59977 | 363 | |
364 | //:f6 abv 29 Apr 98: BUC50070 #3815: make sure that each two edges are | |
365 | // connected by the same vertex; else check that vertices confuse | |
366 | // and make it be one vertex | |
367 | // NOTE: this is done only for the case if at least one of edges | |
368 | // was not yet translated; else nothing will help | |
a90dd15e | 369 | for (j=1; j<=NbEdge; j++) { |
370 | OrEdge1 = EL->EdgeListValue (j); | |
371 | OrEdge2 = EL->EdgeListValue (j < NbEdge ? j + 1 : 1); | |
372 | Handle(StepShape_EdgeCurve) EC1 = | |
373 | Handle(StepShape_EdgeCurve)::DownCast (OrEdge1->EdgeElement()); | |
374 | Handle(StepShape_EdgeCurve) EC2 = | |
375 | Handle(StepShape_EdgeCurve)::DownCast (OrEdge2->EdgeElement()); | |
fa68c1e1 | 376 | if (EC1.IsNull() || EC2.IsNull()) // see #29979 |
377 | { | |
378 | continue; | |
379 | } | |
7fd59977 | 380 | |
a90dd15e | 381 | Handle(StepShape_Vertex) Vs1, Vs2, Vs11, Vs22; |
382 | Vs1 = (OrEdge1->Orientation() ? EC1->EdgeEnd() : EC1->EdgeStart()); | |
383 | Vs2 = (OrEdge2->Orientation() ? EC2->EdgeStart() : EC2->EdgeEnd()); | |
7fd59977 | 384 | |
a90dd15e | 385 | Vs11 = (OrEdge1->Orientation() ? EC1->EdgeStart() : EC1->EdgeEnd()); |
386 | Vs22 = (OrEdge2->Orientation() ? EC2->EdgeEnd() : EC2->EdgeStart()); | |
7fd59977 | 387 | |
a90dd15e | 388 | if ((Vs1 == Vs2) || (Vs1 == Vs22) || (Vs2 == Vs11) || (Vs22 == Vs11)) continue; |
7fd59977 | 389 | |
390 | StepToTopoDS_TranslateVertex myTranVertex1 (Vs1, aTool, NMTool); | |
391 | StepToTopoDS_TranslateVertex myTranVertex2 (Vs2, aTool, NMTool); | |
392 | ||
393 | TopoDS_Vertex V1, V2; | |
a90dd15e | 394 | if (myTranVertex1.IsDone()) |
395 | V1 = TopoDS::Vertex (myTranVertex1.Value()); | |
396 | if (myTranVertex2.IsDone()) | |
397 | V2 = TopoDS::Vertex (myTranVertex2.Value()); | |
398 | if (V1.IsNull() || V2.IsNull()) continue; // not treated | |
399 | if (V1.IsSame(V2)) continue; // OK | |
7fd59977 | 400 | |
401 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
402 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
403 | Standard_Boolean locFixed = Standard_True; | |
404 | if (p1.Distance(p2) <= preci) { | |
a90dd15e | 405 | if (! aTool.IsBound (EC1)) aTool.Bind (Vs1, V2); |
406 | else if (! aTool.IsBound (EC2)) aTool.Bind (Vs2, V1); | |
7fd59977 | 407 | else locFixed = Standard_False; |
408 | } | |
409 | else locFixed = Standard_False; | |
a90dd15e | 410 | if (locFixed) TP->AddWarning(EL, "Adjacent edges do not have common vertex; set confused"); |
411 | else TP->AddWarning(EL, "Adjacent edges are not connected"); | |
7fd59977 | 412 | } |
413 | ||
414 | // ----------------------------------------------- | |
415 | // Iteration on each Oriented Edge of the EdgeLoop | |
416 | // ----------------------------------------------- | |
417 | ||
a90dd15e | 418 | for (j=1; j<=NbEdge; j++) { |
7fd59977 | 419 | |
420 | Standard_Boolean ThereIsLikeSeam = Standard_False; | |
a90dd15e | 421 | |
0797d9d3 | 422 | #ifdef OCCT_DEBUG |
04232180 | 423 | std::cout << " Processing Edge :" << j << std::endl; |
7fd59977 | 424 | #endif |
425 | ||
426 | OrEdge1 = EL->EdgeListValue(j); | |
fa68c1e1 | 427 | |
428 | // see bug #29979: oriented edge contains another oriented edge | |
429 | if (OrEdge1->EdgeElement()->IsKind (STANDARD_TYPE(StepShape_OrientedEdge))) | |
430 | OrEdge1 = Handle(StepShape_OrientedEdge)::DownCast (OrEdge1->EdgeElement()); | |
431 | ||
432 | Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(OrEdge1->EdgeElement()); | |
433 | if (EC.IsNull()) | |
434 | { | |
435 | continue; | |
436 | } | |
a90dd15e | 437 | |
7fd59977 | 438 | // ---------------- |
439 | // Map the StepEdge | |
440 | // ---------------- | |
a90dd15e | 441 | |
7fd59977 | 442 | StepToTopoDS_TranslateEdge myTranEdge; |
a90dd15e | 443 | |
7fd59977 | 444 | myTranEdge.SetPrecision(preci); |
445 | myTranEdge.SetMaxTol(MaxTol()); | |
446 | myTranEdge.Init(OrEdge1, aTool, NMTool); | |
447 | ||
448 | if (myTranEdge.IsDone()) { | |
a90dd15e | 449 | |
7fd59977 | 450 | E = TopoDS::Edge(myTranEdge.Value()); |
451 | if (E.IsNull()) continue; // NULL, on saute | |
452 | ||
453 | Handle(StepGeom_Curve) C = EC->EdgeGeometry(); | |
454 | ||
a90dd15e | 455 | if (OrEdge1->Orientation() && EC->SameSense()) |
456 | E.Orientation(TopAbs_FORWARD); | |
7fd59977 | 457 | else if (!OrEdge1->Orientation() && !EC->SameSense()) |
a90dd15e | 458 | E.Orientation(TopAbs_FORWARD); |
7fd59977 | 459 | else E.Orientation(TopAbs_REVERSED); |
460 | ||
461 | isSeam = isLikeSeam = Standard_False; | |
a90dd15e | 462 | |
7fd59977 | 463 | // ------------------------------------------ |
464 | // Map the StepEdge parametric representation | |
465 | // ------------------------------------------ | |
466 | ||
467 | // -------------------------------------------- | |
468 | // CASE 1 : The Edge Geometry is of Pcurve Type | |
469 | // -------------------------------------------- | |
2a141d40 | 470 | if (C.IsNull()) |
471 | { | |
63c71e2f | 472 | aTool.ComputePCurve(Standard_True); |
473 | hasPcurve = Standard_False; | |
2a141d40 | 474 | } |
475 | else if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) { | |
63c71e2f | 476 | Handle(StepGeom_Pcurve) StepPCurve = Handle(StepGeom_Pcurve)::DownCast(C); |
477 | C2d = myTranEdge.MakePCurve(StepPCurve, ConvSurf); | |
478 | // -- Statistics -- | |
479 | aTool.AddContinuity(C2d); | |
7fd59977 | 480 | } |
481 | ||
482 | // ----------------------------------------- | |
483 | // CASE 2 : The curve is a SurfaceCurve i.e. | |
484 | // - a 3D Curve (mandatory) | |
485 | // - 2 PCurveOrSurface | |
486 | // If modepcurve = 3, PCurve are ignored here | |
487 | // ----------------------------------------- | |
488 | ||
489 | else if (modepcurve == 3) { | |
63c71e2f | 490 | aTool.ComputePCurve(Standard_True); |
491 | hasPcurve = Standard_False; | |
7fd59977 | 492 | } |
63c71e2f | 493 | else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) { |
494 | // recouvre les cas SeamCurve et IntersectionCurve | |
495 | ||
496 | Handle(StepGeom_SurfaceCurve) SurfCurve = | |
497 | Handle(StepGeom_SurfaceCurve)::DownCast(C); | |
498 | ||
499 | Handle(StepGeom_Pcurve) StepPCurve, StepPCurve1, StepPCurve2; | |
500 | Standard_Integer lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve, StepSurf, StepPCurve, 0); | |
501 | hasPcurve = !StepPCurve.IsNull(); | |
502 | ||
503 | // De toute facon, on recalcule | |
504 | ||
505 | if (isPlane) hasPcurve = Standard_False; | |
506 | ||
507 | // ------------------------------------------- | |
508 | // --- Special Mapping Cases : --- | |
509 | // --- the SurfaceCurve is a SeamCurve --- | |
510 | // --- or is like a seam curve --- | |
511 | // --- (see CATIA cylinder) --- | |
512 | // ------------------------------------------- | |
fa68c1e1 | 513 | isLikeSeam = StepToTopoDS_GeometricTool::IsLikeSeam(SurfCurve, StepSurf, EC, EL); |
63c71e2f | 514 | |
fa68c1e1 | 515 | isSeam = StepToTopoDS_GeometricTool::IsSeamCurve(SurfCurve, StepSurf, EC, EL); |
63c71e2f | 516 | |
517 | if (isSeam || isLikeSeam) { | |
518 | // isLikeSeam = Two faces on the same Surface | |
519 | StepPCurve1 = SurfCurve->AssociatedGeometryValue(1).Pcurve(); | |
520 | StepPCurve2 = SurfCurve->AssociatedGeometryValue(2).Pcurve(); | |
521 | if (StepPCurve1.IsNull() || StepPCurve2.IsNull()) hasPcurve = Standard_False; //smh : BUC60810 | |
522 | else { | |
523 | C2d1 = myTranEdge.MakePCurve(StepPCurve1, ConvSurf); | |
524 | C2d2 = myTranEdge.MakePCurve(StepPCurve2, ConvSurf); | |
525 | hasPcurve = (!C2d1.IsNull() && !C2d2.IsNull()); | |
526 | } | |
527 | ||
528 | if (isLikeSeam) { | |
529 | suspectE = E; | |
530 | ThereIsLikeSeam = Standard_True; | |
531 | hasPcurve = Standard_True; | |
532 | } | |
533 | } | |
534 | else if (hasPcurve) { | |
535 | // GeometricTool : Pcurve a retourne StepPCurve | |
536 | while (lastpcurve > 0) { | |
537 | C2d1 = myTranEdge.MakePCurve(StepPCurve, ConvSurf); | |
538 | if (C2d1.IsNull()) { | |
539 | TP->AddWarning(EC, "Incorrect pcurve is not translated. Pcurve definition is not correct"); | |
540 | hasPcurve = Standard_False; | |
541 | break; | |
542 | } | |
543 | else C2d = C2d1; | |
544 | lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve, StepSurf, StepPCurve, lastpcurve); | |
545 | // -- Statistics -- | |
546 | aTool.AddContinuity(C2d); | |
547 | } | |
548 | } | |
549 | if (!hasPcurve) { | |
550 | // The edge geometry has no 2D representation | |
551 | aTool.ComputePCurve(Standard_True); | |
552 | } | |
7fd59977 | 553 | } |
a90dd15e | 554 | |
7fd59977 | 555 | // ---------------------------------------------------------- |
556 | // CASE 3 : The EdgeCurve Geometry is not a Pcurve | |
557 | // nor a SurfaceCurve (i.e. it is a single 3D curve) | |
558 | // ---------------------------------------------------------- | |
559 | ||
560 | else { | |
63c71e2f | 561 | aTool.ComputePCurve(Standard_True); |
562 | hasPcurve = Standard_False; | |
7fd59977 | 563 | } |
a90dd15e | 564 | |
7fd59977 | 565 | // ---------------------------------- |
566 | // update the edge with the pcurve(s) | |
567 | // ---------------------------------- | |
568 | ||
569 | if (hasPcurve && (isSeam || ThereIsLikeSeam)) { | |
570 | ||
63c71e2f | 571 | // ----------------------------------------------------------- |
572 | // The Edge is a Seam Edge : The pcurve wich is FORWARD has to | |
573 | // be identified | |
574 | // ----------------------------------------------------------- | |
575 | ||
576 | if ((!C2d1.IsNull()) && (!C2d2.IsNull())) { | |
577 | TopAbs_Orientation CumulO, EdgeO, WireO, FaceO; | |
578 | EdgeO = E.Orientation(); | |
579 | if (ForwardWire) WireO = TopAbs_FORWARD; | |
580 | else WireO = TopAbs_REVERSED; | |
581 | if (sameSense) FaceO = TopAbs_FORWARD; | |
582 | else FaceO = TopAbs_REVERSED; | |
583 | ||
584 | CumulO = TopAbs::Compose(EdgeO, WireO); | |
585 | CumulO = TopAbs::Compose(CumulO, FaceO); | |
586 | ||
587 | Standard_Boolean ForwardEdge = (CumulO == TopAbs_FORWARD); | |
588 | ||
589 | Standard_Integer forwardPC = | |
590 | ShapeAnalysis_Curve().SelectForwardSeam(C2d1, C2d2); | |
591 | if (forwardPC == 0) { | |
fa68c1e1 | 592 | TP->AddFail(EC, " Seam curve not mapped"); |
63c71e2f | 593 | done = Standard_False; |
594 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
595 | continue; | |
596 | } | |
597 | else if (!ForwardEdge) forwardPC = 3 - forwardPC; // inverser 1-2 | |
598 | ||
599 | if (forwardPC == 1) { | |
600 | if (isSeam) { | |
601 | // When the edge is a Seam, it is better to find the topological | |
602 | // trimming right now. | |
603 | // Remarque : pour bien faire, il faudrait, si necessaire, recalculer | |
604 | // les trois courbes de maniere a ce qu`elles soient | |
605 | // immediatement Same Range et Same Parameter. | |
606 | B.UpdateEdge(E, C2d1, C2d2, Face, 0.); | |
607 | //:S4136 FindParameter(C2d1, C2d2, E, Face, preci); | |
608 | } | |
609 | else | |
610 | B.UpdateEdge(E, C2d1, Face, 0.); //preci | |
611 | } | |
612 | else { | |
613 | if (isSeam) { | |
614 | // When the edge is a Seam, it is better to find the topological | |
615 | // trimming right now. | |
616 | B.UpdateEdge(E, C2d2, C2d1, Face, 0.); | |
617 | //:S4136 FindParameter(C2d1, C2d2, E, Face, preci); | |
618 | } | |
619 | else | |
620 | B.UpdateEdge(E, C2d2, Face, 0.); | |
621 | } | |
622 | } | |
623 | else { | |
fa68c1e1 | 624 | TP->AddFail(EC, " Seam curve not mapped"); |
63c71e2f | 625 | done = Standard_False; |
626 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
627 | continue; | |
628 | } | |
7fd59977 | 629 | } |
630 | else { | |
7fd59977 | 631 | |
63c71e2f | 632 | // --------------------------- |
633 | // The Edge is a "normal" edge | |
634 | // --------------------------- | |
635 | ||
636 | if (hasPcurve) { | |
637 | if (!C2d.IsNull() && !isLikeSeam) { | |
638 | B.UpdateEdge(E, C2d, Face, 0.); | |
639 | } | |
640 | else { | |
fa68c1e1 | 641 | TP->AddFail(EC, " Edge: Trimming of 2D curve failed"); |
63c71e2f | 642 | done = Standard_False; |
643 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
644 | continue; | |
645 | } | |
646 | } | |
7fd59977 | 647 | } |
63c71e2f | 648 | |
649 | if (E.IsNull()) { | |
fa68c1e1 | 650 | TP->AddFail(EC, " an Edge not mapped"); |
63c71e2f | 651 | done = Standard_False; |
652 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
7fd59977 | 653 | } |
654 | } | |
655 | else { // The Edge is Not mapped => switch to next wire ? | |
fa68c1e1 | 656 | TP->AddFail(EC," an Edge not mapped"); |
7fd59977 | 657 | done = Standard_False; |
658 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
7fd59977 | 659 | } |
660 | ||
a90dd15e | 661 | if (done) B.Add (W, E); // on le fait ici. Sauf si erreur rencontree ... ! |
7fd59977 | 662 | else { |
663 | Handle(StepShape_Vertex) Vs1, Vs2; | |
fa68c1e1 | 664 | Vs1 = EC->EdgeStart(); |
665 | Vs2 = EC->EdgeEnd(); | |
a90dd15e | 666 | if (!Vs1.IsNull() && !Vs2.IsNull() && Vs1==Vs2) { |
7fd59977 | 667 | done = Standard_True; |
a90dd15e | 668 | TP->AddFail(EL, " Edge with equal vertices failed, scipped"); |
7fd59977 | 669 | } |
670 | } | |
671 | } | |
672 | ||
673 | // The EdgeLoop is binded in the Wire | |
674 | ||
675 | if (!done) { | |
a90dd15e | 676 | TP->AddFail(EL, "At least one edge failed : wire not done"); |
7fd59977 | 677 | return; |
678 | } | |
ab860031 | 679 | W.Closed (BRep_Tool::IsClosed (W)); |
7fd59977 | 680 | aTool.Bind(EL, W); |
a90dd15e | 681 | |
7fd59977 | 682 | // ---------------------------------------------- |
683 | // Computes the 2D parameter of Vertices on Edges | |
684 | // ---------------------------------------------- | |
63c71e2f | 685 | //pdn compute parameter of Vertices using projecting |
a90dd15e | 686 | if (!aTool.ComputePCurve()) |
687 | for (TopoDS_Iterator EdgeIt(W);EdgeIt.More();EdgeIt.Next()) { | |
7fd59977 | 688 | TopoDS_Edge edge = TopoDS::Edge(EdgeIt.Value()); |
689 | Handle(ShapeFix_EdgeProjAux) myEdgePro = ShapeAlgo::AlgoContainer()->ToolContainer()->EdgeProjAux(); | |
690 | myEdgePro->Init (Face, edge); | |
691 | myEdgePro->Compute(preci); | |
692 | if (myEdgePro->IsFirstDone() && myEdgePro->IsLastDone()) { | |
e65d641a A |
693 | if (Abs (myEdgePro->FirstParam() - myEdgePro->LastParam()) < Precision::PConfusion()) |
694 | continue; | |
a90dd15e | 695 | B.Range(edge, Face, myEdgePro->FirstParam(), myEdgePro->LastParam()); |
7fd59977 | 696 | } |
697 | else { | |
698 | RemoveSinglePCurve(edge, Face); | |
0797d9d3 | 699 | #ifdef OCCT_DEBUG |
04232180 | 700 | std::cout <<"Removing after prj"<<std::endl; |
7fd59977 | 701 | #endif |
702 | } | |
a90dd15e | 703 | } |
704 | ||
7fd59977 | 705 | myResult = W; |
706 | myError = StepToTopoDS_TranslateEdgeLoopDone; | |
707 | done = Standard_True; | |
708 | // Check des PCurves SYSTEMATIQUE, s il n y en a que quelques unes | |
a90dd15e | 709 | CheckPCurves (W, Face, isPlane, preci); |
7fd59977 | 710 | |
7fd59977 | 711 | return; |
712 | } | |
713 | ||
714 | ||
715 | // ============================================================================ | |
716 | // Method : Value | |
717 | // Purpose : Return the mapped Shape | |
718 | // ============================================================================ | |
719 | ||
a90dd15e | 720 | const TopoDS_Shape& StepToTopoDS_TranslateEdgeLoop::Value() const |
7fd59977 | 721 | { |
2d2b3d53 | 722 | StdFail_NotDone_Raise_if (!done, "StepToTopoDS_TranslateEdgeLoop::Value() - no result"); |
7fd59977 | 723 | return myResult; |
724 | } | |
725 | ||
726 | // ============================================================================ | |
727 | // Method : Error | |
728 | // Purpose : Return the TranslateEdgeLoop error | |
729 | // ============================================================================ | |
730 | ||
731 | StepToTopoDS_TranslateEdgeLoopError StepToTopoDS_TranslateEdgeLoop::Error() const | |
732 | { | |
733 | return myError; | |
734 | } | |
735 |