1 // Created on: 1995-01-27
2 // Created by: Marie Jose MARTZ
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
9 // under the terms of the GNU Lesser General Public 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 //:q4 abv 16.03.99: PRO17828 face 555: transform pcurves on SurfaceOfRevolution
19 //S4181 pdn implementing of writing IGES elementary surfaces.
21 #include <BRepToIGES_BRWire.ixx>
23 #include <BRep_Tool.hxx>
24 #include <BRepTools.hxx>
25 #include <BRepTools_WireExplorer.hxx>
28 #include <gp_Ax2d.hxx>
29 #include <gp_Dir2d.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Trsf.hxx>
33 #include <gp_Trsf2d.hxx>
35 #include <Geom_CartesianPoint.hxx>
36 #include <Geom_ConicalSurface.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_CylindricalSurface.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <Geom_SphericalSurface.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_SurfaceOfLinearExtrusion.hxx>
44 #include <Geom_SurfaceOfRevolution.hxx>
45 #include <Geom_ToroidalSurface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_Line.hxx>
51 #include <GeomToIGES_GeomPoint.hxx>
52 #include <GeomToIGES_GeomCurve.hxx>
54 #include <Geom2dToIGES_Geom2dCurve.hxx>
56 #include <IGESData_HArray1OfIGESEntity.hxx>
57 #include <IGESData_IGESEntity.hxx>
58 #include <IGESData_IGESModel.hxx>
60 #include <IGESGeom_CompositeCurve.hxx>
61 #include <IGESGeom_Point.hxx>
63 #include <Interface_Macros.hxx>
65 #include <Precision.hxx>
67 #include <TColStd_HSequenceOfTransient.hxx>
70 #include <TopoDS_Vertex.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Wire.hxx>
73 #include <TopoDS_Shape.hxx>
75 #include <TopAbs_ShapeEnum.hxx>
76 #include <TopAbs_Orientation.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <Interface_Static.hxx>
80 #include <ShapeBuild_Edge.hxx>
81 #include <Geom_OffsetSurface.hxx>
82 #include <ShapeExtend_WireData.hxx>
83 #include <ShapeFix_Wire.hxx>
86 //=============================================================================
88 //=============================================================================
90 BRepToIGES_BRWire::BRepToIGES_BRWire()
95 //=============================================================================
97 //=============================================================================
99 BRepToIGES_BRWire::BRepToIGES_BRWire
100 (const BRepToIGES_BREntity& BR)
101 : BRepToIGES_BREntity(BR)
106 //=============================================================================
108 //=============================================================================
110 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
111 (const TopoDS_Shape& start)
113 Handle(IGESData_IGESEntity) res;
115 if (start.IsNull()) return res;
117 if (start.ShapeType() == TopAbs_VERTEX) {
118 TopoDS_Vertex V = TopoDS::Vertex(start);
119 res = TransferVertex(V);
121 else if (start.ShapeType() == TopAbs_EDGE) {
122 TopoDS_Edge E = TopoDS::Edge(start);
123 res = TransferEdge(E, Standard_False);
125 else if (start.ShapeType() == TopAbs_WIRE) {
126 TopoDS_Wire W = TopoDS::Wire(start);
127 res = TransferWire(W);
136 //=============================================================================
139 //=============================================================================
141 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
142 (const TopoDS_Vertex& myvertex)
144 Handle(IGESData_IGESEntity) res;
145 if ( myvertex.IsNull()) return res;
147 Handle(Geom_CartesianPoint) Point;
148 Point = new Geom_CartesianPoint(BRep_Tool::Pnt(myvertex));
149 Handle(IGESData_IGESEntity) IVertex;
150 if (!Point.IsNull()) {
151 GeomToIGES_GeomPoint GP;
152 GP.SetModel(GetModel());
153 IVertex = GP.TransferPoint(Point);
156 if (!IVertex.IsNull()) res = IVertex;
161 //=============================================================================
164 //=============================================================================
166 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
167 (const TopoDS_Vertex& myvertex,
168 const TopoDS_Edge& myedge,
169 Standard_Real& parameter)
171 Handle(IGESData_IGESEntity) res;
172 if ( myvertex.IsNull()) return res;
174 Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
176 // returns the parameter of myvertex on myedge
177 parameter = BRep_Tool::Parameter(myvertex,myedge);
179 if (!IVertex.IsNull()) res = IVertex;
184 //=============================================================================
187 //=============================================================================
189 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
190 (const TopoDS_Vertex& myvertex,
191 const TopoDS_Edge& myedge,
192 const TopoDS_Face& myface,
193 Standard_Real& parameter)
195 Handle(IGESData_IGESEntity) res;
196 if ( myvertex.IsNull()) return res;
198 Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
200 // returns the parameter of myvertex on the pcurve of myedge on myface
201 parameter = BRep_Tool::Parameter(myvertex, myedge, myface);
203 if (!IVertex.IsNull()) res = IVertex;
208 //=============================================================================
211 //=============================================================================
213 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
214 (const TopoDS_Vertex& myvertex,
215 const TopoDS_Edge& myedge,
216 const Handle(Geom_Surface)& mysurface,
217 const TopLoc_Location& myloc,
218 Standard_Real& parameter)
220 Handle(IGESData_IGESEntity) res;
221 if ( myvertex.IsNull()) return res;
223 Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
225 // returns the parameter of myvertex on the pcurve of myedge on mysurface
226 parameter = BRep_Tool::Parameter(myvertex, myedge, mysurface, myloc);
228 if (!IVertex.IsNull()) res = IVertex;
233 //=============================================================================
236 //=============================================================================
238 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferVertex
239 (const TopoDS_Vertex& myvertex,
240 const TopoDS_Face& myface,
243 Handle(IGESData_IGESEntity) res;
244 if ( myvertex.IsNull()) return res;
246 Handle(IGESData_IGESEntity) IVertex = TransferVertex(myvertex);
248 // returns the parameter of myvertex on myface
249 mypoint = BRep_Tool::Parameters(myvertex, myface);
251 if (!IVertex.IsNull()) res = IVertex;
256 //=============================================================================
258 //=============================================================================
260 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferEdge
261 (const TopoDS_Edge& myedge,
262 const Standard_Boolean isBRepMode)
264 Handle(IGESData_IGESEntity) res;
265 if ( myedge.IsNull()) return res;
267 // returns the 3d curve of the edge and the parameter range
269 Standard_Real First, Last, U1, U2;
270 Handle(IGESData_IGESEntity) ICurve;
271 Handle(Geom_Curve) Curve3d = BRep_Tool::Curve(myedge, L, First, Last);
273 //#28 rln 19.10.98 UKI60155, etc.
274 //Only Bezier will be converted into B-Spline, not Conic. This conertation
275 //will be done only inside GeomToIGES package for simplifying the code.
278 //Unnecessary duplication of curves is removed.
280 if (!Curve3d.IsNull()) {
281 gp_Trsf Tr = L.Transformation();
282 if (Tr.Form() != gp_Identity)
283 Curve3d = Handle(Geom_Curve)::DownCast(Curve3d->Transformed (Tr));
285 Curve3d = Handle(Geom_Curve)::DownCast(Curve3d->Copy());
287 if (myedge.Orientation() == TopAbs_REVERSED && !isBRepMode) {
288 U1 = Curve3d->ReversedParameter(Last);
289 U2 = Curve3d->ReversedParameter(First);
297 GeomToIGES_GeomCurve GC;
298 GC.SetModel(GetModel());
299 ICurve = GC.TransferCurve(Curve3d, U1, U2);
303 //Vertices are not translated into IGES anymore since they are not put into
306 if (!ICurve.IsNull()) res = ICurve;
308 SetShapeResult ( myedge, res );
314 //=============================================================================
316 //=============================================================================
318 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferEdge (const TopoDS_Edge& myedge,
319 const TopoDS_Face& myface,
320 const Standard_Real length,
321 const Standard_Boolean isBRepMode)
323 Handle(IGESData_IGESEntity) res;
324 if ( myedge.IsNull() || GetPCurveMode() ==0 ||
325 ( ! isBRepMode && BRep_Tool::Degenerated ( myedge ) ) ) return res;
327 //S4181 pdn 23.04.99 adjusting length factor according to analytic mode.
328 Standard_Real myLen = length;
329 Standard_Boolean analyticMode = ( GetConvertSurfaceMode() ==0 && isBRepMode );
331 // returns the 2d curve associated to myedge in the parametric space of myface
332 Standard_Real First, Last;
333 Handle(Geom2d_Curve) Curve2d = BRep_Tool::CurveOnSurface(myedge, myface, First, Last);
334 Handle(IGESData_IGESEntity) ICurve2d;
337 if (!Curve2d.IsNull()) {
338 // For "revolution" and "LinearExtrusion" surfaces, it is necessary
339 // to apply a translation of 2D curves to agree on the
340 // origin (U,V) between IGES and BRep (for Cylindrical,
341 // Conical and SurfaceOfLinearExtrusion)
342 // It is necessary to invert (u,v) surfaces of revolution.
345 Handle(Geom_Surface) st = BRep_Tool::Surface(myface, L);
346 if (st->IsKind(STANDARD_TYPE(Geom_Plane))){
349 Standard_Real Ufirst, Ulast, Vfirst, Vlast;
350 BRepTools::UVBounds(myface, Ufirst, Ulast, Vfirst, Vlast);
351 Handle(Geom_Surface) Surf;
353 if (st->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
354 DeclareAndCast(Geom_RectangularTrimmedSurface, rectang, st);
355 Surf = rectang->BasisSurface();
360 //:abv 19.06.02: writing (loopback) on file offseted_sphere.rle in BRep mode
361 if (st->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
362 DeclareAndCast(Geom_OffsetSurface, offset, Surf);
363 Surf = offset->BasisSurface();
366 //S4181 pdn 20.04.99 transformation of pcurves id defined by type of surface
367 // and analytic mode.
368 // skl 18.07.2005 for OCC9490 : in following if() commented
369 // condition for SurfaceOfLinearExtrusion
370 Standard_Boolean needShift = (!analyticMode&&
371 ((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) ||
372 (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))/* ||
373 (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)))*/));
374 //:q4 abv 16 Mar 99: PRO17828 face 555: shift pcurves on SurfaceOfRevolution
375 if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
376 Handle(Geom_SurfaceOfRevolution) rev =
377 Handle(Geom_SurfaceOfRevolution)::DownCast ( Surf );
378 Handle(Geom_Curve) curve = rev->BasisCurve();
379 // skl 31.05.2004 for OCC6004
380 if(curve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
381 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(curve);
382 curve = tc->BasisCurve();
384 if ( curve->IsKind(STANDARD_TYPE(Geom_Line)) ) needShift = Standard_True;
388 TR.SetTranslation(gp_Pnt2d(0.,0.),gp_Pnt2d(0.,-Vfirst));
389 Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Transformed(TR));
391 else Curve2d = Handle(Geom2d_Curve)::DownCast(Curve2d->Copy());
393 if (!analyticMode&&((Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) ||
394 (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) ||
395 (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))))) {
396 //#30 rln 19.10.98 transformation of pcurves for IGES Surface of Revolution
397 Curve2d->Mirror (gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
398 Curve2d->Mirror (gp::OX2d());
399 Curve2d->Translate (gp_Vec2d (0, 2 * M_PI));
402 if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))||
403 (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))){
404 Curve2d->Mirror (gp_Ax2d (gp::Origin2d(), gp_Dir2d (1.,1.)));
405 Curve2d->Mirror (gp::OX2d());
406 Curve2d->Translate (gp_Vec2d (0, 2 * M_PI));
409 if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
410 Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))))
413 if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
414 Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))) {
416 trans.SetScale(gp_Pnt2d(0,0),180./M_PI);
417 Curve2d->Transform(trans);
418 First = Curve2d->TransformedParameter(First,trans);
419 Last = Curve2d->TransformedParameter(Last, trans);
422 if (analyticMode&&(Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))) {
423 Handle(Geom_ConicalSurface) con = Handle(Geom_ConicalSurface)::DownCast ( Surf );
424 if(con->SemiAngle() < 0) {
425 Standard_Real vApex = 2 * con->RefRadius() / Sin (con->SemiAngle());
426 Curve2d->Translate (gp_Vec2d (0, vApex));
429 //S4181 transfer functionality
431 Standard_Real uFact = 1.;
432 if(isBRepMode && Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
433 trans.SetScale(gp_Pnt2d(0,0),1./GetUnit());
435 if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
436 Standard_Real aDiv = myLen;
437 if(aDiv < gp::Resolution())
439 //emv: changed for bug OCC22126 17.12.2010
440 trans.SetScale(gp_Pnt2d(0,0), 1. / (Vlast - Vfirst));
443 //added by skl 18.07.2005 for OCC9490
444 // trans.SetScale(gp_Pnt2d(0,0),1./Vlast);
446 Standard_Real du = 1.;
447 Standard_Real us1,us2,vs1,vs2;
448 //scaling parameterization to [0,1]
449 Surf->Bounds(us1,us2,vs1,vs2);
451 //emv: changed for bug OCC22126 17.12.2010
452 uFact = (Vlast - Vfirst)/du;
455 if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
456 Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface)) ||
457 Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) { //:q4
462 Curve2d = sbe.TransformPCurve(Curve2d,trans,uFact,First,Last);
463 // (Curve2d, Surf, First, Last, myLen, isBRepMode);
464 // if the edge is REVERSED, it is necessary to "REVERSE" the curve 2d.
466 // added by skl 18.07.2005 for OCC9490
467 if(Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
468 //emv: changed for bug OCC22126 17.12.2010
470 Standard_Real us1,us2,vs1,vs2,du;
471 //computing shift of pcurves
472 Surf->Bounds(us1,us2,vs1,vs2);
474 trans1.SetTranslation(gp_Vec2d(-us1/du,-Vfirst/(Vlast-Vfirst)));
475 Curve2d = sbe.TransformPCurve(Curve2d,trans1,1.,First,Last);
478 if (myedge.Orientation() == TopAbs_REVERSED) {
479 Standard_Real tmpFirst = Curve2d->ReversedParameter(Last),
480 tmpLast = Curve2d->ReversedParameter(First);
485 Geom2dToIGES_Geom2dCurve GC;
486 GC.SetModel(GetModel());
487 ICurve2d = GC.Transfer2dCurve(Curve2d, First, Last);
491 //Vertices are not translated into IGES anymore since they are not put into
494 if (!ICurve2d.IsNull()) res = ICurve2d;
496 SetShapeResult ( myedge, res );
502 //=============================================================================
504 //=============================================================================
506 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
507 (const TopoDS_Wire& mywire)
509 Handle(IGESData_IGESEntity) res;
510 if ( mywire.IsNull()) return res;
512 //A composite curve is defined as an ordered list of entities
513 //consisting of a point, connect point and parametrised curve
514 //entities (excluding the CompositeCurve entity).
516 Handle(IGESData_IGESEntity) ent ;
517 Handle(TColStd_HSequenceOfTransient) Seq = new TColStd_HSequenceOfTransient();
519 TopExp_Explorer TE(mywire, TopAbs_VERTEX);
521 BRepTools_WireExplorer WE;
522 for ( WE.Init(mywire); WE.More(); WE.Next()) {
523 TopoDS_Edge E = WE.Current();
525 AddWarning(mywire, "an Edge is a null entity");
528 ent = TransferEdge(E, Standard_False);
529 if (!ent.IsNull()) Seq->Append(ent);
534 AddWarning(mywire, " no Vertex associated to the Wire");
537 Standard_Integer nbedges = Seq->Length();
538 Handle(IGESData_HArray1OfIGESEntity) Tab;
539 if ( nbedges == 1 ) {
542 else if ( nbedges >= 2) {
543 Tab = new IGESData_HArray1OfIGESEntity(1,nbedges);
544 for (Standard_Integer itab = 1; itab <= nbedges; itab++) {
545 Handle(IGESData_IGESEntity) item = GetCasted(IGESData_IGESEntity, Seq->Value(itab));
546 Tab->SetValue(itab,item);
548 Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
553 SetShapeResult ( mywire, res );
559 //=============================================================================
561 //=============================================================================
563 Handle(IGESData_IGESEntity) BRepToIGES_BRWire ::TransferWire
564 (const TopoDS_Wire & mywire,
565 const TopoDS_Face & myface,
566 Handle(IGESData_IGESEntity)& mycurve2d,
567 const Standard_Real length)
569 Handle(IGESData_IGESEntity) res;
570 if ( mywire.IsNull()) return res;
572 Handle(IGESData_IGESEntity) ent3d ;
573 Handle(IGESData_IGESEntity) ent2d ;
574 Handle(TColStd_HSequenceOfTransient) Seq3d = new TColStd_HSequenceOfTransient();
575 Handle(TColStd_HSequenceOfTransient) Seq2d = new TColStd_HSequenceOfTransient();
578 // create a 3d CompositeCurve and a 2d CompositeCurve
579 TopExp_Explorer TE(mywire, TopAbs_VERTEX);
581 // PTV OCC908 workaround for KAS:dev version
583 BRepTools_WireExplorer WE;
584 for ( WE.Init(mywire,myface); WE.More(); WE.Next()) {
585 TopoDS_Edge E = WE.Current();
587 AddWarning(mywire, "an Edge is a null entity");
590 ent3d = TransferEdge(E, Standard_False);
591 if (!ent3d.IsNull()) Seq3d->Append(ent3d);
592 ent2d = TransferEdge(E, myface, length, Standard_False);
593 if (!ent2d.IsNull()) Seq2d->Append(ent2d);
597 Handle(ShapeFix_Wire) aSFW =
598 new ShapeFix_Wire( mywire, myface, Precision::Confusion() );
600 Handle(ShapeExtend_WireData) aSEWD = aSFW->WireData();
601 Standard_Integer nbE = aSEWD->NbEdges();
602 for (Standard_Integer windex = 1; windex <= nbE; windex++) {
603 TopoDS_Edge E = aSEWD->Edge( windex );
605 AddWarning(mywire, "an Edge is a null entity");
608 ent3d = TransferEdge(E, Standard_False);
609 if (!ent3d.IsNull()) Seq3d->Append(ent3d);
610 ent2d = TransferEdge(E, myface, length, Standard_False);
611 if (!ent2d.IsNull()) Seq2d->Append(ent2d);
614 // OCC908 end of workaround
617 AddWarning(mywire, " no Vertex associated to the Wire");
619 // Composite Curve 3D
620 Standard_Integer nb3d = Seq3d->Length();
621 Handle(IGESData_HArray1OfIGESEntity) Tab3d;
625 else if (nb3d >= 2) {
626 Tab3d = new IGESData_HArray1OfIGESEntity(1,nb3d);
627 //Standard_Integer tabval = nb3d; //szv#4:S4163:12Mar99 unused
628 for (Standard_Integer itab = 1; itab <= nb3d; itab++) {
629 Handle(IGESData_IGESEntity) item =
630 GetCasted(IGESData_IGESEntity, Seq3d->Value(itab));
631 Tab3d->SetValue(itab,item);
633 Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
638 // Composite Curve 2D
639 Standard_Integer nb2d = Seq2d->Length();
640 Handle(IGESData_HArray1OfIGESEntity) Tab2d;
644 else if (nb2d >= 2) {
645 Tab2d = new IGESData_HArray1OfIGESEntity(1,nb2d);
646 //Standard_Integer tabval = nb2d; //szv#4:S4163:12Mar99 unused
647 for ( Standard_Integer itab = 1; itab <= nb2d; itab++) {
648 Handle(IGESData_IGESEntity) item =
649 GetCasted(IGESData_IGESEntity, Seq2d->Value(itab));
650 Tab2d->SetValue(itab,item);
652 Handle(IGESGeom_CompositeCurve) Comp = new IGESGeom_CompositeCurve;
657 SetShapeResult ( mywire, res );