0025418: Debug output to be limited to OCC development environment
[occt.git] / src / StepToTopoDS / StepToTopoDS_TranslateEdge.cxx
CommitLineData
b311480e 1// Created on: 1995-01-03
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//:o0 abv 16.02.99: POLYLINE allowed as 3d curve of edge
18//gka,abv 05.04.99: S4136: improving tolerance management, eliminate BRepAPI::Precision()
19
20#include <StepToTopoDS_TranslateEdge.ixx>
21
22#include <StepToTopoDS.hxx>
23#include <StepToTopoDS_TranslateVertex.hxx>
24#include <StepToTopoDS_GeometricTool.hxx>
25#include <StepToGeom_MakeCurve.hxx>
26
27#include <TopoDS.hxx>
28#include <TopoDS_Edge.hxx>
29#include <BRep_Builder.hxx>
30#include <BRep_Tool.hxx>
31#include <BRepLib.hxx>
32#include <BRepLib_MakeEdge.hxx>
33#include <Geom_Curve.hxx>
34#include <GeomAbs_Shape.hxx>
35
36#include <Geom_Line.hxx>
37#include <gp_Vec.hxx>
38#include <gp_Dir.hxx>
39#include <gp_Lin.hxx>
40
41#include <ShapeAnalysis_Curve.hxx>
42#include <ShapeConstruct_Curve.hxx>
43
44#include <StepShape_EdgeCurve.hxx>
45#include <StepShape_OrientedEdge.hxx>
46#include <StepGeom_Curve.hxx>
47//#include <StepGeom_Polyline.hxx>
48#include <StepGeom_Pcurve.hxx>
49#include <StepGeom_SurfaceCurve.hxx>
50#include <Transfer_TransientProcess.hxx>
51//#include <TransferBRep.hxx>
52
53#include <GeomAdaptor_Curve.hxx>
54#include <GCPnts_AbscissaPoint.hxx>
55#include <Precision.hxx>
56
57#include <StepToGeom_MakeCurve2d.hxx>
58#include <StepRepr_DefinitionalRepresentation.hxx>
59#include <UnitsMethods.hxx>
60
61//:d8
62#include <StepShape_VertexPoint.hxx>
63#include <StepGeom_CartesianPoint.hxx>
64#include <StepToGeom_MakeCartesianPoint.hxx>
65#include <Geom_CartesianPoint.hxx>
66
67// Used in I-DEAS-like STP processing (ssv; 15.11.2010)
68#include <TCollection_HAsciiString.hxx>
69
70//#define DEBUG
71
72
73// ============================================================================
74// Method : DecodeMakeEdgeError
75// Purpose :
76// ============================================================================
77
78static void DecodeMakeEdgeError(const BRepLib_MakeEdge& ME,
79 const Handle(Standard_Transient)& orig,
80 const Handle(Geom_Curve)& myCurve,
81 const TopoDS_Vertex& V1,
82 const TopoDS_Vertex& V2,
0797d9d3 83 const Standard_Real& U1,
84 const Standard_Real& U2,
7fd59977 85 StepToTopoDS_Tool& aTool,
86 const Handle(StepShape_TopologicalRepresentationItem)& /*tobind*/)
87{
0797d9d3 88 (void)U1, (void)U2; // avoid compiler warning
89
7fd59977 90 Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
91// if (!myCurve.IsNull() && !tobind.IsNull()) {
92// TransferBRep::SetShapeResult
93// (TP,tobind, MakeEdge(myCurve,V1,V2,U1,U2,BRepAPI::Precision()) );
94// aTool.Bind (tobind,E); SURTOUT PAS : noter pour debug/erreur
95// }
0797d9d3 96#ifdef OCCT_DEBUG
7fd59977 97 cout << "------------------------------------" << endl;
98 cout << "MakeEdge Error : " << ME.Error()<<" - ";
99#endif
100 switch(ME.Error())
101 {
102 case (BRepLib_EdgeDone): return;
103 case (BRepLib_PointProjectionFailed):
104 TP->AddFail(orig," Point Projection failed");
105 break;
106 case (BRepLib_ParameterOutOfRange):
107 TP->AddFail(orig," Parameter Out Of Range");
108 break;
109 case (BRepLib_DifferentPointsOnClosedCurve):
110 TP->AddFail(orig," Different Points on Closed Curve");
111 break;
112 case (BRepLib_PointWithInfiniteParameter):
113 TP->AddFail(orig," Point with infinite Parameter");
114 break;
115 case (BRepLib_DifferentsPointAndParameter):
116 if (!ShapeConstruct_Curve().AdjustCurve
117 (myCurve,BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2),Standard_True,Standard_True))
118 TP->AddFail(orig," Different Points and Parameters");
119 else TP->AddWarning(orig,"Different Points and Parameters, adjusted");
120 break;
121 case (BRepLib_LineThroughIdenticPoints):
122 TP->AddFail(orig," Line through identic Points");
123 break;
124 }
0797d9d3 125#ifdef OCCT_DEBUG
7fd59977 126 cout << "Original Type : " << orig->DynamicType() << endl;
127 cout << "3D Curve Type : " << myCurve->DynamicType() << endl;
128 cout << "First Parameter : " << U1 << endl;
129 gp_Pnt p1 = BRep_Tool::Pnt(V1);
130// cout << "First Point : ";
131 cout << "First Vertex : "<<p1.X()<<" "<<p1.Y()<<" "<<p1.Z()<<" ";
132 cout << "Distance Point - Vertex : ";
133 Standard_Real d1 = p1.Distance(myCurve->Value(U1));
134 cout << d1 << endl;
135 cout << "Last Parameter : " << U2 << endl;
136 gp_Pnt p2 = BRep_Tool::Pnt(V2);
137// cout << "Last Point : ";
138 cout << "Last Vertex : "<<p2.X()<<" "<<p2.Y()<<" "<<p2.Z()<<" ";
139 cout << "Distance Point - Vertex : ";
140 Standard_Real d2 = BRep_Tool::Pnt(V2).Distance(myCurve->Value(U2));
141 cout << d2 << endl;
142#endif
143}
144
145// ============================================================================
146// Method : StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge
147// Purpose : Empty Constructor
148// ============================================================================
149
150static Handle(Geom_Curve) MakeCurve
151 (const Handle(StepGeom_Curve)& C1, const Handle(Transfer_TransientProcess) TP)
152{
153 Handle(Geom_Curve) C2 = Handle(Geom_Curve)::DownCast (TP->FindTransient(C1));
154 if (!C2.IsNull()) return C2;
155 if (StepToGeom_MakeCurve::Convert(C1,C2))
156 TP->BindTransient (C1,C2);
157 return C2;
158}
159
160static TopoDS_Edge MakeEdge
161 (const Handle(Geom_Curve)& C3D,
162 const TopoDS_Vertex& V1, const TopoDS_Vertex& V2,
163 const Standard_Real U1, const Standard_Real U2) //, const Standard_Real preci)
164{
165// fait son edge quoi qu il arrive
166 BRep_Builder B;
167 TopoDS_Edge E;
168 B.MakeEdge (E,C3D,Precision::Confusion());//preci);
169 B.Add (E,V1); B.Add (E,V2);
170 B.UpdateVertex(V1, U1, E, 0.);//preci);
171 B.UpdateVertex(V2, U2, E, 0.);//preci);
172 return E;
173}
174
175StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge()
176{
177 done = Standard_False;
178}
179
180// ============================================================================
181// Method : StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge()
182// Purpose : Constructor with an Edge and a Tool
183// ============================================================================
184
185StepToTopoDS_TranslateEdge::StepToTopoDS_TranslateEdge(const Handle(StepShape_Edge)& E,
186 StepToTopoDS_Tool& T,
187 StepToTopoDS_NMTool& NMTool)
188{
189 Init(E, T, NMTool);
190}
191
192// ============================================================================
193// Method : Init
194// Purpose : Init with an Edge and a Tool.
195// This method builds an Edge With 2 Vertices and 2 Parameters.
196// The Edge is always build like FORWARD (BRepLib_MakeEdge)
197// ============================================================================
198
199void StepToTopoDS_TranslateEdge::Init(const Handle(StepShape_Edge)& aEdge,
200 StepToTopoDS_Tool& aTool,
201 StepToTopoDS_NMTool& NMTool)
202{
203 Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
204
205 Handle(StepShape_OrientedEdge) OE =
206 Handle(StepShape_OrientedEdge)::DownCast(aEdge);
207 Handle(StepShape_Edge) wEdge = aEdge;
208 if ( ! OE.IsNull() ) wEdge = OE->EdgeElement();
209 Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(wEdge);
210
211 if (aTool.IsBound(EC)) {
212 myResult = aTool.Find(EC);
213 if (BRep_Tool::Degenerated(TopoDS::Edge(myResult))) {
214 TP->AddWarning(EC,"Degenerated Edge in several faces : transferred for each face");
215 }
216 else {
217 myError = StepToTopoDS_TranslateEdgeDone;
218 done = Standard_True;
219// BRep_Builder B;
220//:S4136 B.SameRange(TopoDS::Edge(myResult), Standard_False); //:a5 abv 11 Feb 98
221//:S4136 B.SameParameter(TopoDS::Edge(myResult), Standard_False);//:a5
222 return;
223 }
224 }
225
226 // [BEGIN] Proceed with non-manifold cases (ssv; 12.11.2010)
227 if ( NMTool.IsActive() && NMTool.IsBound(EC) ) {
228 TopoDS_Shape existingShape = NMTool.Find(EC);
229 // Reverse shape's orientation if needed
230 if ( !OE->Orientation() )
231 existingShape.Reverse();
232 myResult = existingShape;
233 myError = StepToTopoDS_TranslateEdgeDone;
234 done = Standard_True;
235 return;
236 }
237 // [END] Proceed with non-manifold cases (ssv; 12.11.2010)
238
239 // [BEGIN] Proceed with I-DEAS-like STP (ssv; 15.11.2010)
240 const Handle(TCollection_HAsciiString) anECName = EC->Name();
241 if ( NMTool.IsIDEASCase() && !anECName.IsNull() && !anECName->IsEmpty() &&
242 NMTool.IsBound(anECName->String()) ) {
243 TopoDS_Shape existingShape = NMTool.Find(anECName->String());
244 // Reverse shape's orientation if needed
245 if ( !OE->Orientation() )
246 existingShape.Reverse();
247 // Register Edge for final processing (I-DEAS case)
248 NMTool.RegisterNMEdge(existingShape);
249 myResult = existingShape;
250 myError = StepToTopoDS_TranslateEdgeDone;
251 done = Standard_True;
252 return;
253 }
254 // [END] Proceed with I-DEAS-like STP (ssv; 15.11.2010)
255
256 BRep_Builder B;
257
258// Standard_Real preci = BRepAPI::Precision();
259
260// Standard_Real precision = BRepAPI::Precision();
261
262 Handle(StepGeom_Curve) C = EC->EdgeGeometry();
545ef510 263 if( C.IsNull())
264 {
265 TP->AddFail(EC," Geom Curve in EdgeCurve is equal to 0");
266 myError = StepToTopoDS_TranslateEdgeOther;
267 done = Standard_False;
268 return;
269 }
7fd59977 270 TopoDS_Edge E;
271 Handle(StepShape_Vertex) Vstart, Vend;
272
273 // -----------------------------------------------------------
274 // Extract the start and end Vertices corresponding to FORWARD
275 // (following the geometrical sense)
276 // -----------------------------------------------------------
277
278// Standard_Boolean OrientedEdgeOrientation = OE->Orientation();
279 Standard_Boolean EdgeCurveSameSense = EC->SameSense();
280
281 if (EdgeCurveSameSense) {
282 Vstart = EC->EdgeStart();
283 Vend = EC->EdgeEnd();
284 }
285 else {
286 Vend = EC->EdgeStart();
287 Vstart = EC->EdgeEnd();
288 }
289
290 TopoDS_Vertex V1, V2;
291
292 StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool);
293 StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool);
294
295 if (myTranVertex1.IsDone()) {
296 V1 = TopoDS::Vertex(myTranVertex1.Value());
297 V1.Orientation(TopAbs_FORWARD);
298 }
299 if (Vend == Vstart) {
300 V2 = V1;
301 V2.Orientation(TopAbs_REVERSED);
302 }
303 else if (myTranVertex2.IsDone()) {
304 V2 = TopoDS::Vertex(myTranVertex2.Value());
305 V2.Orientation(TopAbs_REVERSED);
306 }
307 done = Standard_True;
308
309 // ----------------------------------------------------------
310 // --- The EdgeCurve Geometry is of StepGeom_Curve Type
311 // --- It can be : * a Pcurve : no 3D curve is constructed
312 // --- * a Surface Curve, Intersection Curve
313 // --- or a Seam Curve
314 // --- * a 3D Curve
315 // ----------------------------------------------------------
316
317 if ( C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) {
318 B.MakeEdge(E);
319//:S4136 B.UpdateEdge (E,preci);
320 B.Add(E, V1); // ?? en fin de TranslateEdgeLoop
321 B.Add(E, V2);
322 }
323 else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve)) ) {
324 // qui reprend les types SeamCurve et IntersectionCurve
325 // --- The Edge Geometry is a Surface Curve ---
326 // --- (3d + 2 Pcurve Or Surface) ---
327 Handle(StepGeom_SurfaceCurve) Sc =
328 Handle(StepGeom_SurfaceCurve)::DownCast(C);
329 Handle(StepGeom_Curve) C1 = Sc->Curve3d();
330// if (C1->IsKind(STANDARD_TYPE(StepGeom_Polyline))) {
331// B.MakeEdge(E);
332// B.UpdateEdge (E,preci);
333// B.Add(E, V1); // ?? en fin de TranslateEdgeLoop
334// B.Add(E, V2);
335// }
336// else {
337 MakeFromCurve3D (C1,EC,Vend,Precision(), E,V1,V2 , aTool);
338// }
339 }
340// else if (C->IsKind(STANDARD_TYPE(StepGeom_Polyline))) {
341// B.MakeEdge(E);
342// B.UpdateEdge (E,preci);
343// B.Add(E, V1); // ?? en fin de TranslateEdgeLoop
344// B.Add(E, V2);
345// }
346 else {
347 // --- The Edge Geometry is a Single 3d Curve ---
348 MakeFromCurve3D (C,EC,Vend,Precision(), E,V1,V2 , aTool);
349 }
350 // On force les flags SameRange et SameParameter a Standard_False
351 if (done) {
352//:S4136 B.SameRange(E, Standard_False);
353//:S4136 B.SameParameter(E, Standard_False);
354 aTool.Bind(EC,E);
355
356 // Bind Edge in NM tool (ssv; 15.11.2010)
357 if ( NMTool.IsActive() ) {
358 NMTool.Bind(EC, E);
359 if ( NMTool.IsIDEASCase() && !anECName.IsNull() && !anECName->IsEmpty() )
360 NMTool.Bind(anECName->String(), E);
361 }
362
363 myResult = E;
364 myError = StepToTopoDS_TranslateEdgeDone;
365 }
366}
367
368
369// ============================================================================
370// Method : MakeFromCurve3D
371// Purpose : case of a Curve 3D (alone or in SurfaceCurve)
372// ============================================================================
373
374// auxiliary function
375//:e6 abv 16 Apr 98: ProSTEP TR8, r0601_sy.stp, #14907
376static void GetCartesianPoints ( const Handle(StepShape_EdgeCurve)& EC,
377 gp_Pnt &P1, gp_Pnt &P2)
378{
379 for ( Standard_Integer i=1; i<=2; i++ ) {
380 const Handle(StepShape_Vertex) V = ( (Standard_Boolean)(i==1) == EC->SameSense() ? EC->EdgeStart() : EC->EdgeEnd() );
381 const Handle(StepShape_VertexPoint) VP = Handle(StepShape_VertexPoint)::DownCast(V);
382 if ( VP.IsNull() ) continue;
383 const Handle(StepGeom_CartesianPoint) P = Handle(StepGeom_CartesianPoint)::DownCast(VP->VertexGeometry());
384 Handle(Geom_CartesianPoint) CP;
385 StepToGeom_MakeCartesianPoint::Convert(P,CP);
386 ( i==1 ? P1 : P2 ) = CP->Pnt();
387 }
388}
389
390void StepToTopoDS_TranslateEdge::MakeFromCurve3D
391 (const Handle(StepGeom_Curve)& C3D, const Handle(StepShape_EdgeCurve)& EC,
392 const Handle(StepShape_Vertex)& Vend,
393 const Standard_Real preci, TopoDS_Edge& E,
394 TopoDS_Vertex& V1, TopoDS_Vertex& V2,
395 StepToTopoDS_Tool& aTool)
396{
397 Handle(Transfer_TransientProcess) TP = aTool.TransientProcess();
398 Handle(Geom_Curve) C1 = MakeCurve(C3D,TP);
399 if (C1.IsNull()) {
400 TP->AddFail(C3D," Make Geom_Curve (3D) failed");
401 myError = StepToTopoDS_TranslateEdgeOther;
402 done = Standard_False;
403 return;
404 }
405 // -- Statistics -- -> No Warning message
406 aTool.AddContinuity (C1);
407 BRep_Builder B;
408 Standard_Real temp1,temp2, U1,U2;
409 gp_Pnt pproj;
410 gp_Pnt pv1 = BRep_Tool::Pnt(V1);
411 gp_Pnt pv2 = BRep_Tool::Pnt(V2);
412
413 //:e6 abv
414 gp_Pnt pnt1 = pv1, pnt2 = pv2;
415 if ( V1.IsSame ( V2 ) ) GetCartesianPoints ( EC, pnt1, pnt2 );
416 ShapeAnalysis_Curve sac;
417 temp1 = sac.Project (C1,pnt1,preci,pproj,U1,Standard_False);
418 temp2 = sac.Project (C1,pnt2,preci,pproj,U2,Standard_False);
419
420 if (!StepToTopoDS_GeometricTool::UpdateParam3d(C1, U1, U2, preci))
421 TP->AddWarning(C3D,"Update of 3D-Parameters has failed");
422
423 //:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends
424 gp_Pnt pU1 = C1->Value ( U1 ), pU2 = C1->Value ( U2 );
425 temp1 = pU1.Distance ( pv1 );
426 temp2 = pU2.Distance ( pv2 );
427 if ( temp1 > preci || temp2 > preci ) {
428 TP->AddWarning (C3D,"Poor result from projection vertex / curve 3d");
429 }
430 B.UpdateVertex ( V1, 1.000001*temp1 ); //:h6 abv 14 Jul 98: PRO8845 #2746: *=1.0001
431 B.UpdateVertex ( V2, 1.000001*temp2 ); //:h6
432
433 BRepLib_MakeEdge ME(C1, V1, V2, U1, U2);
434 if (ME.IsDone()) {
435 E = ME.Edge();
436 B.Range ( E, U1, U2 ); // abv 14 Mar 00: trj3_pm1-ug.stp #91739, edge 2
437 }
438 else {
439 if (ME.Error() == BRepLib_DifferentPointsOnClosedCurve) {
440 // The Edge could be closed and trimmed by 2 Differents
441 // Vertices
442 if (C1->IsClosed()) {
443 // Attention : il faudra mettre a jour la topologie des
444 // vertex pour avoir des edges cul a cul ...... Good Luck!
445 aTool.Bind (Vend,V1);
446 TopoDS_Shape aLocalShape = V1.Reversed();
447 V2 = TopoDS::Vertex(aLocalShape);
448 ME.Init(C1, V1, V2, U1, U2);
449 if (ME.IsDone()) {
450 TP->AddWarning(EC, "Wrong topology corrected : Closed Edge with TWO different Vertices");
451 E = ME.Edge();
452 }
453 else {
454 DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
455 E = MakeEdge (C1,V1,V2,U1,U2);//preci
456 myError = StepToTopoDS_TranslateEdgeDone; // ????
457 done = Standard_True;
458 // return;
459 }
460 }
461 else {
462 // Then, this is should be coded as degenerated
463 // To be performed later !!!
464// DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
465 myError = StepToTopoDS_TranslateEdgeDone; // ????
466 // Bon, on la fait cette petite edge, mais faudra repasser
467 // pour l enlever ET FUSIONNER LES VERTEX, pour tout le shell !
468 // courbe trop petite pour etre mise -> fait planter
469 done = Standard_True;
470 if (!V1.IsSame(V2)) {
471 TP->AddFail(EC, "This edge has null arc length");
472 gp_Pnt P1 = BRep_Tool::Pnt(V1);
473 gp_Pnt P2 = BRep_Tool::Pnt(V2);
474 gp_Vec avec (P1,P2); gp_Dir adir (avec); gp_Lin alin (P1,adir);
475 C1 = new Geom_Line (alin);
476 U1 = 0.; U2 = P1.Distance(P2);
477 E = MakeEdge (C1,V1,V2,U1,U2);//,preci
478 }
479 else {
480 TP->AddFail(EC,"NULL EDGE, SKIPPED");
481 myResult.Nullify();
482 return;
483 }
484 }
485 }
486 else {
487 DecodeMakeEdgeError(ME, C3D, C1, V1, V2, U1, U2, aTool, EC);
488 E = MakeEdge (C1,V1,V2,U1,U2);//,preci
489 myError = StepToTopoDS_TranslateEdgeDone; // ????
490 done = Standard_True;
491 }
492 }
493}
494
495
496// ============================================================================
497// Method : MakePCurve
498// Purpose : Computes an individual pcurve (i.e. curve 2d)
499// ============================================================================
500Handle(Geom2d_Curve) StepToTopoDS_TranslateEdge::MakePCurve
501 (const Handle(StepGeom_Pcurve)& PCU, const Handle(Geom_Surface)& ConvSurf) const
502{
503 Handle(Geom2d_Curve) C2d;
504 const Handle(StepRepr_DefinitionalRepresentation) DRI = PCU->ReferenceToCurve();
505 if( DRI.IsNull()) return C2d;
506 const Handle(StepGeom_Curve) StepCurve = Handle(StepGeom_Curve)::DownCast(DRI->ItemsValue(1));
507 if (StepToGeom_MakeCurve2d::Convert(StepCurve,C2d)) {
508 // -- if the surface is a RectangularTrimmedSurface,
509 // -- send the BasisSurface.
510 C2d = UnitsMethods::DegreeToRadian(C2d, ConvSurf);
511 }
512 return C2d;
513}
514
515
516// ============================================================================
517// Method : Value
518// Purpose : Returns the mapped edge
519// ============================================================================
520
521const TopoDS_Shape& StepToTopoDS_TranslateEdge::Value() const
522{
523 StdFail_NotDone_Raise_if(!done,"");
524 return myResult;
525}
526
527// ============================================================================
528// Method : Error
529// Purpose : Returns the error code
530// ============================================================================
531
532StepToTopoDS_TranslateEdgeError StepToTopoDS_TranslateEdge::Error() const
533{
534 return myError;
535}