1 // Created on: 2011-10-14
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Adaptor3d_HCurve.hxx>
17 #include <Adaptor3d_IsoCurve.hxx>
18 #include <Bnd_Box.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepMesh_IncrementalMesh.hxx>
21 #include <BRepBndLib.hxx>
22 #include <BRepMesh_DiscretFactory.hxx>
23 #include <BRepMesh_DiscretRoot.hxx>
24 #include <BRepTools.hxx>
25 #include <Hatch_Hatcher.hxx>
26 #include <GCPnts_QuasiUniformDeflection.hxx>
27 #include <GCPnts_TangentialDeflection.hxx>
28 #include <Geom_BezierSurface.hxx>
29 #include <Geom_BSplineSurface.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <GeomAdaptor_Curve.hxx>
32 #include <gp_Dir2d.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <IVtkOCC_ShapeMesher.hxx>
35 #include <NCollection_Array1.hxx>
36 #include <Poly_Polygon3D.hxx>
37 #include <Poly_PolygonOnTriangulation.hxx>
38 #include <Poly_Triangulation.hxx>
39 #include <Precision.hxx>
41 #include <Prs3d_Drawer.hxx>
42 #include <Quantity_Length.hxx>
43 #include <Standard_ErrorHandler.hxx>
44 #include <TColgp_SequenceOfPnt2d.hxx>
45 #include <TColStd_Array1OfReal.hxx>
47 #include <TopExp_Explorer.hxx>
49 // Handle implementation
52 //================================================================
53 // Function : internalBuild
55 //================================================================
56 void IVtkOCC_ShapeMesher::internalBuild()
58 // TODO: do we need any protection here so as not to triangualte
59 // the shape twice??? This can be done e.g. by checking if
60 // triangulation exists for TopoDS_Shape..
63 // Free vertices and free edges should always be shown.
64 // Shared edges are needed in WF representation only.
65 // TODO: how to filter free edges at visualization level????
69 // Build wireframe points and cells (lines for isolines)
72 // Build shaded representation (based on Poly_Triangulation)
76 //================================================================
77 // Function : GetShapeObj
79 //================================================================
80 const IVtkOCC_Shape::Handle IVtkOCC_ShapeMesher::GetShapeObj() const
82 return (IVtkOCC_Shape::Handle::DownCast(myShapeObj));
85 //================================================================
86 // Function : GetDeflection
87 // Purpose : Returns absolute deflection used by this algorithm.
88 //================================================================
89 Standard_Real IVtkOCC_ShapeMesher::GetDeflection() const
91 if (myDeflection < Precision::Confusion()) // if not yet initialized
93 Handle(Prs3d_Drawer) aDefDrawer = new Prs3d_Drawer();
94 aDefDrawer->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
95 aDefDrawer->SetDeviationCoefficient (GetDeviationCoeff());
96 myDeflection = Prs3d::GetDeflection (GetShapeObj()->GetShape(), aDefDrawer);
102 //================================================================
103 // Function : meshShape
105 //================================================================
106 void IVtkOCC_ShapeMesher::meshShape()
108 TopoDS_Shape anOcctShape = GetShapeObj()->GetShape();
109 if (anOcctShape.IsNull())
114 //Clean triangulation before compute incremental mesh
115 BRepTools::Clean (anOcctShape);
117 //Compute triangulation
118 Standard_Real aDeflection = GetDeflection();
119 if (aDeflection < Precision::Confusion())
128 Handle(BRepMesh_DiscretRoot) anAlgo;
129 anAlgo = BRepMesh_DiscretFactory::Get().Discret (anOcctShape,
131 GetDeviationAngle());
132 if (!anAlgo.IsNull())
137 catch (Standard_Failure)
141 //================================================================
142 // Function : addFreeVertices
144 //================================================================
145 void IVtkOCC_ShapeMesher::addFreeVertices()
147 TopTools_IndexedDataMapOfShapeListOfShape aVertexMap;
148 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
153 Standard_Integer aVertNum = aVertexMap.Extent();
155 for (Standard_Integer anIt = 1; anIt <= aVertNum; anIt++)
157 if (aVertexMap.FindFromIndex(anIt).IsEmpty())
159 aType = MT_FreeVertex;
163 aType = MT_SharedVertex;
165 TopoDS_Vertex aVertex = TopoDS::Vertex (aVertexMap.FindKey (anIt));
166 addVertex (aVertex, GetShapeObj()->GetSubShapeId (aVertex), aType);
170 //================================================================
171 // Function : addEdges
173 //================================================================
174 void IVtkOCC_ShapeMesher::addEdges()
176 TopTools_IndexedDataMapOfShapeListOfShape anEdgesMap;
177 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
184 myEdgesTypes.Clear();
186 TopExp_Explorer anEdgeIter (GetShapeObj()->GetShape(), TopAbs_EDGE);
187 for (; anEdgeIter.More(); anEdgeIter.Next())
189 TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current());
190 aNbFaces = anEdgesMap.FindFromKey (anOcctEdge).Extent();
195 else if (aNbFaces == 1)
197 aType = MT_BoundaryEdge;
201 aType = MT_SharedEdge;
203 addEdge (anOcctEdge, GetShapeObj()->GetSubShapeId (anOcctEdge), aType);
204 myEdgesTypes.Bind (anOcctEdge, aType);
208 //================================================================
209 // Function : addWireFrameFaces
211 //================================================================
212 void IVtkOCC_ShapeMesher::addWireFrameFaces()
214 // Check the deflection value once for all faces
215 if (GetDeflection() < Precision::Confusion())
220 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
221 for (; aFaceIter.More(); aFaceIter.Next())
223 TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current());
227 addWFFace (anOcctFace,
228 GetShapeObj()->GetSubShapeId (anOcctFace));
230 catch (Standard_Failure)
235 //================================================================
236 // Function : addShadedFaces
238 //================================================================
239 void IVtkOCC_ShapeMesher::addShadedFaces()
241 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
242 for (; aFaceIter.More(); aFaceIter.Next())
244 TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current());
245 addShadedFace (anOcctFace,
246 GetShapeObj()->GetSubShapeId (anOcctFace));
250 //================================================================
251 // Function : addVertex
253 //================================================================
254 void IVtkOCC_ShapeMesher::addVertex (const TopoDS_Vertex& theVertex,
255 const IVtk_IdType theShapeId,
256 const IVtk_MeshType theMeshType)
258 if (theVertex.IsNull())
263 gp_Pnt aPnt3d = BRep_Tool::Pnt (theVertex);
266 myShapeData->InsertCoordinate (aPnt3d.X(), aPnt3d.Y(), aPnt3d.Z());
267 myShapeData->InsertVertex (theShapeId, anId, theMeshType);
271 //================================================================
272 // Function : processPolyline
274 //================================================================
275 void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer theNbNodes,
276 const TColgp_Array1OfPnt& thePoints,
277 const TColStd_Array1OfInteger& thePointIds,
278 const IVtk_IdType theOcctId,
280 gp_Trsf theTransformation,
281 const IVtk_MeshType theMeshType)
288 IVtk_PointIdList *aPolyPointIds = new IVtk_PointIdList();
291 for (Standard_Integer aJ = 0; aJ < theNbNodes; aJ++)
293 Standard_Integer aPntId = thePointIds (aJ + 1);
294 gp_Pnt point = thePoints (aPntId);
298 // Apply the transformation to points
299 point.Transform (theTransformation);
302 anId = myShapeData->InsertCoordinate (point.X(), point.Y(), point.Z());
303 aPolyPointIds->Append (anId);
306 myShapeData->InsertLine (theOcctId, aPolyPointIds, theMeshType);
308 delete aPolyPointIds;
311 //================================================================
312 // Function : addEdge
314 //================================================================
315 void IVtkOCC_ShapeMesher::addEdge (const TopoDS_Edge& theEdge,
316 const IVtk_IdType theShapeId,
317 const IVtk_MeshType theMeshType)
319 if (theEdge.IsNull() || BRep_Tool::Degenerated (theEdge))
324 // Two discrete representations of an OCCT edge are possible:
325 // 1. Polygon on trinagulation - holds Ids of points
326 // contained in Poly_Triangulation object
327 Handle(Poly_PolygonOnTriangulation) aPolyOnTriangulation;
328 Handle(Poly_Triangulation) aTriangulation;
329 TopLoc_Location aLocation;
330 BRep_Tool::PolygonOnTriangulation (theEdge,
331 aPolyOnTriangulation,
336 // 2. 3D polygon - holds 3D points
337 Handle(Poly_Polygon3D) aPoly3d;
338 if (aPolyOnTriangulation.IsNull())
340 aPoly3d = BRep_Tool::Polygon3D (theEdge, aLocation);
343 if (aPoly3d.IsNull() && aPolyOnTriangulation.IsNull())
348 // Handle a non-identity transofmation applied to the edge
349 gp_Trsf anEdgeTransf;
350 bool noTransform = true;
351 if (!aLocation.IsIdentity())
354 anEdgeTransf = aLocation.Transformation();
357 if (!aPoly3d.IsNull())
359 Standard_Integer aNbNodes = aPoly3d->NbNodes();
360 const TColgp_Array1OfPnt& aPoints = aPoly3d->Nodes();
361 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
363 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
365 aPointIds.SetValue (anI, anI);
368 processPolyline (aNbNodes,
378 Standard_Integer aNbNodes = aPolyOnTriangulation->NbNodes();
379 const TColStd_Array1OfInteger& aPointIds = aPolyOnTriangulation->Nodes();
380 const TColgp_Array1OfPnt& aPoints = aTriangulation->Nodes();
382 processPolyline (aNbNodes,
393 //================================================================
394 // Function : FindLimits
395 // Purpose : Static internal function, finds parametrical limits of the curve.
396 //! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry
397 //! @param [in] theLimit maximum allowed absolute parameter value
398 //! @param [out] theFirst minimum parameter value for the curve
399 //! @param [out] theLast maximum parameter value for the curve
400 //================================================================
401 static void FindLimits (const Adaptor3d_Curve& theCurve,
402 const Standard_Real& theLimit,
403 Standard_Real& theFirst,
404 Standard_Real& theLast)
406 theFirst = Max(theCurve.FirstParameter(), theFirst);
407 theLast = Min(theCurve.LastParameter(), theLast);
408 Standard_Boolean isFirstInf = Precision::IsNegativeInfinite (theFirst);
409 Standard_Boolean isLastInf = Precision::IsPositiveInfinite (theLast);
411 if (isFirstInf || isLastInf)
414 Standard_Real aDelta = 1;
415 if (isFirstInf && isLastInf)
422 theCurve.D0 (theFirst, aP1);
423 theCurve.D0 (theLast, aP2);
424 } while (aP1.Distance (aP2) < theLimit);
428 theCurve.D0 (theLast, aP2);
431 theFirst = theLast - aDelta;
432 theCurve.D0 (theFirst, aP1);
433 } while (aP1.Distance(aP2) < theLimit);
437 theCurve.D0 (theFirst, aP1);
441 theLast = theFirst + aDelta;
442 theCurve.D0 (theLast, aP2);
443 } while (aP1.Distance (aP2) < theLimit);
448 //================================================================
449 // Function : FindLimits
450 // Purpose :Static helper function, builds a discrete representation
451 //! (sequence of points) for the given curve.
453 //! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry
454 //! @param [in] theDeflection absolute deflection value
455 //! @param [in] theAngle deviation angle value
456 //! @param [in] theU1 minimal curve parameter value
457 //! @param [in] theU2 maximal curve parameter value
458 //! @param [out] thePoints the container for generated polyline
459 //================================================================
460 static void DrawCurve (Adaptor3d_Curve& theCurve,
461 const Quantity_Length theDeflection,
462 const Standard_Real theAngle,
463 const Standard_Real theU1,
464 const Standard_Real theU2,
465 IVtk_Polyline& thePoints)
467 switch (theCurve.GetType())
471 gp_Pnt aPnt = theCurve.Value(theU1);
472 thePoints.Append (aPnt);
474 aPnt = theCurve.Value(0.5 * (theU1 + theU2));
475 thePoints.Append (aPnt);
477 aPnt = theCurve.Value (theU2);
478 thePoints.Append(aPnt);
483 Standard_Integer aNbInter = theCurve.NbIntervals(GeomAbs_C1);
484 Standard_Integer anI, aJ;
485 TColStd_Array1OfReal aParams(1, aNbInter+1);
486 theCurve.Intervals(aParams, GeomAbs_C1);
487 Standard_Real theU1, theU2;
488 Standard_Integer NumberOfPoints;
490 for (aJ = 1; aJ <= aNbInter; aJ++)
492 theU1 = aParams (aJ); theU2 = aParams (aJ + 1);
493 if (theU2 > theU1 && theU1 < theU2)
495 theU1 = Max(theU1, theU1);
496 theU2 = Min(theU2, theU2);
498 GCPnts_TangentialDeflection anAlgo (theCurve, theU1, theU2, theAngle, theDeflection);
499 NumberOfPoints = anAlgo.NbPoints();
501 if (NumberOfPoints > 0)
503 for (anI = 1; anI < NumberOfPoints; anI++)
505 thePoints.Append(anAlgo.Value (anI));
509 thePoints.Append (anAlgo.Value (NumberOfPoints));
518 //================================================================
519 // Function : buildIsoLines
521 //================================================================
522 void IVtkOCC_ShapeMesher::buildIsoLines (const Handle(BRepAdaptor_HSurface)& theFace,
523 const Standard_Boolean theIsDrawUIso,
524 const Standard_Boolean theIsDrawVIso,
525 const Standard_Integer theNBUiso,
526 const Standard_Integer theNBViso,
527 IVtk_PolylineList& thePolylines)
529 Standard_Real anUF, anUL, aVF, aVL;
530 anUF = theFace->FirstUParameter();
531 anUL = theFace->LastUParameter();
532 aVF = theFace->FirstVParameter();
533 aVL = theFace->LastVParameter();
535 // Restrict maximal parameter value
536 // in OCCT it's 5e+5 by default
537 const Standard_Real aLimit = 5e+5;
539 // compute bounds of the restriction
540 Standard_Real anUMin, anUMax, aVMin, aVMax;
541 Standard_Integer anI;
543 anUMin = Max (anUF, -aLimit);
544 anUMax = Min (anUL, aLimit);
545 aVMin = Max (aVF, -aLimit);
546 aVMax = Min (aVL, aLimit);
548 // update min max for the hatcher.
552 Standard_Real aDdefle = Max (anUMax - anUMin, aVMax - aVMin) * GetDeviationCoeff();
553 TColgp_SequenceOfPnt2d aTabPoints;
555 anUMin = aVMin = 1.e100;
556 anUMax = aVMax = -1.e100;
559 TopExp_Explorer aToolRst;
560 TopoDS_Face aTopoFace (((BRepAdaptor_Surface*)&(theFace->Surface()))->Face());
561 for (aToolRst.Init (aTopoFace, TopAbs_EDGE); aToolRst.More(); aToolRst.Next())
563 TopAbs_Orientation anOrient = aToolRst.Current().Orientation();
564 // Skip INTERNAL and EXTERNAL edges
565 if (anOrient == TopAbs_FORWARD || anOrient == TopAbs_REVERSED)
567 Standard_Real anU1, anU2;
568 const Handle(Geom2d_Curve)& aCurve =
569 BRep_Tool::CurveOnSurface (TopoDS::Edge (aToolRst.Current()),
577 Geom2dAdaptor_Curve aRCurve;
578 aRCurve.Load (aCurve, anU1, anU2);
579 if (aRCurve.GetType() != GeomAbs_Line)
581 GCPnts_QuasiUniformDeflection aUDP(aRCurve, aDdefle);
584 Standard_Integer NumberOfPoints = aUDP.NbPoints();
585 if ( NumberOfPoints >= 2 )
587 aDummyPnt = aUDP.Value (1);
588 aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y());
589 anUMin = Min (aP2.X(), anUMin);
590 anUMax = Max (aP2.X(), anUMax);
591 aVMin = Min (aP2.Y(), aVMin);
592 aVMax = Max (aP2.Y(), aVMax);
593 for (anI = 2; anI <= NumberOfPoints; anI++)
596 aDummyPnt = aUDP.Value (anI);
597 aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y());
598 anUMin = Min(aP2.X(), anUMin);
599 anUMax = Max(aP2.X(), anUMax);
600 aVMin = Min(aP2.Y(), aVMin);
601 aVMax = Max(aP2.Y(), aVMax);
603 if(anOrient == TopAbs_FORWARD )
605 //isobuild.Trim(P1,P2);
606 aTabPoints.Append (aP1);
607 aTabPoints.Append (aP2);
611 //isobuild.Trim(P2,P1);
612 aTabPoints.Append (aP2);
613 aTabPoints.Append (aP1);
620 cout << "Cannot evaluate curve on surface"<<endl;
625 anU1 = aRCurve.FirstParameter();
626 anU2 = aRCurve.LastParameter();
627 // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
628 // ensure that distance U2-U1 is not greater than aLimit*2,
629 // if greater then choose an origin and use aLimit to define
631 Standard_Real aOrigin = 0.;
632 if (!Precision::IsNegativeInfinite(anU1) || !Precision::IsPositiveInfinite (anU2))
634 if (Precision::IsNegativeInfinite (anU1))
636 aOrigin = anU2 - aLimit;
638 else if (Precision::IsPositiveInfinite (anU2))
640 aOrigin = anU1 + aLimit;
644 aOrigin = (anU1 + anU2) * 0.5;
648 anU1 = Max (aOrigin - aLimit, anU1);
649 anU2 = Min (aOrigin + aLimit, anU2);
650 aP1 = aRCurve.Value (anU1);
651 aP2 = aRCurve.Value (anU2);
652 anUMin = Min(aP1.X(), anUMin);
653 anUMax = Max(aP1.X(), anUMax);
654 aVMin = Min(aP1.Y(), aVMin);
655 aVMax = Max(aP1.Y(), aVMax);
656 anUMin = Min(aP2.X(), anUMin);
657 anUMax = Max(aP2.X(), anUMax);
658 aVMin = Min(aP2.Y(), aVMin);
659 aVMax = Max(aP2.Y(), aVMax);
660 if(anOrient == TopAbs_FORWARD )
662 // isobuild.Trim(P1,P2);
663 aTabPoints.Append (aP1);
664 aTabPoints.Append (aP2);
668 //isobuild.Trim(P2,P1);
669 aTabPoints.Append (aP2);
670 aTabPoints.Append (aP1);
677 const Standard_Real anIntersectionTolerance = 1.e-5;
678 Hatch_Hatcher anIsoBuild (anIntersectionTolerance, Standard_True );
680 Standard_Boolean isUClosed = theFace->IsUClosed();
681 Standard_Boolean isVClosed = theFace->IsVClosed();
685 anUMin = anUMin + (anUMax - anUMin) / 1000.0;
686 anUMax = anUMax - (anUMax - anUMin) /1000.0;
691 aVMin = aVMin + (aVMax - aVMin) /1000.0;
692 aVMax = aVMax - (aVMax - aVMin) /1000.0;
699 isUClosed = Standard_False;
700 Standard_Real aDu= isUClosed ? (anUMax - anUMin) / theNBUiso : (anUMax - anUMin) / (1 + theNBUiso);
701 for (anI = 1; anI <= theNBUiso; anI++)
703 anIsoBuild.AddXLine (anUMin + aDu*anI);
711 isVClosed = Standard_False;
712 Standard_Real aDv= isVClosed ? (aVMax - aVMin) / theNBViso : (aVMax - aVMin) / (1 + theNBViso);
713 for (anI = 1; anI <= theNBViso; anI++)
715 anIsoBuild.AddYLine (aVMin + aDv*anI);
720 Standard_Integer aLength = aTabPoints.Length();
721 for (anI = 1; anI <= aLength; anI += 2)
723 anIsoBuild.Trim (aTabPoints (anI),aTabPoints (anI + 1));
726 // Create the polylines for isos
727 Adaptor3d_IsoCurve anIso;
729 Handle(Geom_Curve) aBCurve;
730 const BRepAdaptor_Surface& aBSurf = *(BRepAdaptor_Surface*)&(theFace->Surface());
731 GeomAbs_SurfaceType aType = theFace->GetType();
733 Standard_Integer aNumberOfLines = anIsoBuild.NbLines();
734 Handle(Geom_Surface) aGeomSurf;
735 if (aType == GeomAbs_BezierSurface)
737 aGeomSurf = aBSurf.Bezier();
739 else if (aType == GeomAbs_BSplineSurface)
741 aGeomSurf = aBSurf.BSpline();
744 Standard_Real aDeflection = GetDeflection();
745 Standard_Real anAngle = GetDeviationAngle();
746 for (anI = 1; anI <= aNumberOfLines; anI++)
748 Standard_Integer aNumberOfIntervals = anIsoBuild.NbIntervals(anI);
749 Standard_Real aCoord = anIsoBuild.Coordinate(anI);
750 for (Standard_Integer aJ = 1; aJ <= aNumberOfIntervals; aJ++)
752 Standard_Real aB1 = anIsoBuild.Start (anI, aJ);
753 Standard_Real aB2 = anIsoBuild.End(anI, aJ);
755 if (!aGeomSurf.IsNull())
757 if (anIsoBuild.IsXLine (anI))
759 aBCurve = aGeomSurf->UIso (aCoord);
763 aBCurve = aGeomSurf->VIso (aCoord);
766 GeomAdaptor_Curve aGeomCurve (aBCurve);
767 FindLimits (aGeomCurve, aLimit, aB1, aB2);
768 if (aB2 - aB1 > Precision::Confusion())
770 IVtk_Polyline aPoints;
771 DrawCurve (aGeomCurve, aDeflection, anAngle, aB1, aB2, aPoints);
772 thePolylines.Append (aPoints);
777 if (anIsoBuild.IsXLine (anI))
779 anIso.Load (GeomAbs_IsoU, aCoord, aB1, aB2);
783 anIso.Load (GeomAbs_IsoV, aCoord, aB1, aB2);
785 FindLimits (anIso, aLimit, aB1, aB2);
786 if (aB2 - aB1>Precision::Confusion())
788 IVtk_Polyline aPoints;
789 DrawCurve (anIso, aDeflection, anAngle, aB1, aB2, aPoints);
790 thePolylines.Append (aPoints);
797 //================================================================
798 // Function : addWFFace
800 //================================================================
801 void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace,
802 const IVtk_IdType theShapeId)
804 if (theFace.IsNull())
809 TopoDS_Face aFaceToMesh = theFace;
810 aFaceToMesh.Orientation (TopAbs_FORWARD);
812 // The code that builds wireframe representation for a TopoDS_Face
813 // has been adapted from some OCCT 6.5.1 methods:
814 // - Prs3d_WFShape::Add()
815 // - StdPrs_WFDeflectionRestrictedFace::Add()
816 // - StdPrs_DeflectionCurve::Add()
818 // Add face's edges here but with the face ID
819 TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE );
820 for (; anEdgeIter.More(); anEdgeIter.Next())
822 TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current());
823 addEdge (anOcctEdge, theShapeId, myEdgesTypes (anOcctEdge));
826 TopLoc_Location aLoc;
827 const Handle(Geom_Surface)& aGeomSurf = BRep_Tool::Surface (aFaceToMesh, aLoc);
828 if (aGeomSurf.IsNull())
833 BRepAdaptor_Surface aSurf;
834 aSurf.Initialize (aFaceToMesh);
835 Handle(BRepAdaptor_HSurface) aSurfAdaptor = new BRepAdaptor_HSurface (aSurf);
837 IVtk_PolylineList aPolylines;
840 // Building U isolines
841 // Introducing a local scope here to simplify variable naming
843 buildIsoLines (aSurfAdaptor,
850 IVtk_PolylineList::Iterator anIt (aPolylines);
851 for (; anIt.More(); anIt.Next())
853 const IVtk_Polyline& aPntSeq = anIt.Value();
854 Standard_Integer aNbNodes = aPntSeq.Length();
855 TColgp_Array1OfPnt aPoints (1, aNbNodes);
856 for (Standard_Integer aJ = 1; aJ <= aNbNodes; aJ++)
858 aPoints.SetValue (aJ, aPntSeq.Value(aJ));
861 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
862 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
864 aPointIds.SetValue (anI, anI);
867 processPolyline (aNbNodes,
877 // Building V isolines
880 buildIsoLines (aSurfAdaptor,
887 IVtk_PolylineList::Iterator anIt (aPolylines);
888 for (; anIt.More(); anIt.Next())
890 const IVtk_Polyline& aPntSeq = anIt.Value();
891 Standard_Integer aNbNodes = aPntSeq.Length();
892 TColgp_Array1OfPnt aPoints (1, aNbNodes);
893 for (int aJ = 1; aJ <= aNbNodes; aJ++)
895 aPoints.SetValue (aJ, aPntSeq.Value (aJ));
898 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
899 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
901 aPointIds.SetValue (anI, anI);
904 processPolyline (aNbNodes,
915 //================================================================
916 // Function : addShadedFace
918 //================================================================
919 void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
920 const IVtk_IdType theShapeId)
922 if (theFace.IsNull())
927 // Build triangulation of the face.
928 TopLoc_Location aLoc;
929 Handle(Poly_Triangulation) anOcctTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
930 if (anOcctTriangulation.IsNull())
935 gp_Trsf aPntTransform;
936 Standard_Boolean noTransform = Standard_True;
937 if (!aLoc.IsIdentity())
939 noTransform = Standard_False;
940 aPntTransform = aLoc.Transformation();
943 // Get triangulation points.
944 const TColgp_Array1OfPnt& aPoints = anOcctTriangulation->Nodes();
945 Standard_Integer aNbPoints = anOcctTriangulation->NbNodes();
947 // Keep inserted points id's of triangulation in an array.
948 NCollection_Array1<IVtk_PointId> aPointIds (1, aNbPoints);
951 Standard_Integer anI;
952 for (anI = 1; anI <= aNbPoints; anI++)
954 gp_Pnt aPoint = aPoints (anI);
958 aPoint.Transform (aPntTransform);
961 // Add a point into output shape data and keep its id in the array.
962 anId = myShapeData->InsertCoordinate (aPoint.X(), aPoint.Y(), aPoint.Z());
963 aPointIds.SetValue (anI, anId);
966 // Create triangles on the created triangulation points.
967 const Poly_Array1OfTriangle& aTriangles = anOcctTriangulation->Triangles();
968 Standard_Integer aNbTriangles = anOcctTriangulation->NbTriangles();
969 Standard_Integer aN1, aN2, aN3;
970 for (anI = 1; anI <= aNbTriangles; anI++)
972 aTriangles(anI).Get (aN1, aN2, aN3); // get indexes of triangle's points
973 // Insert new triangle on these points into output shape data.
974 myShapeData->InsertTriangle (
975 theShapeId, aPointIds(aN1), aPointIds(aN2), aPointIds(aN3), MT_ShadedFace);