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