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 IMPLEMENT_STANDARD_RTTIEXT(IVtkOCC_ShapeMesher,IVtk_IShapeMesher)
51 // Handle implementation
54 //================================================================
55 // Function : internalBuild
57 //================================================================
58 void IVtkOCC_ShapeMesher::internalBuild()
60 // TODO: do we need any protection here so as not to triangualte
61 // the shape twice??? This can be done e.g. by checking if
62 // triangulation exists for TopoDS_Shape..
65 // Free vertices and free edges should always be shown.
66 // Shared edges are needed in WF representation only.
67 // TODO: how to filter free edges at visualization level????
71 // Build wireframe points and cells (lines for isolines)
74 // Build shaded representation (based on Poly_Triangulation)
78 //================================================================
79 // Function : GetShapeObj
81 //================================================================
82 const IVtkOCC_Shape::Handle IVtkOCC_ShapeMesher::GetShapeObj() const
84 return (IVtkOCC_Shape::Handle::DownCast(myShapeObj));
87 //================================================================
88 // Function : GetDeflection
89 // Purpose : Returns absolute deflection used by this algorithm.
90 //================================================================
91 Standard_Real IVtkOCC_ShapeMesher::GetDeflection() const
93 if (myDeflection < Precision::Confusion()) // if not yet initialized
95 Handle(Prs3d_Drawer) aDefDrawer = new Prs3d_Drawer();
96 aDefDrawer->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
97 aDefDrawer->SetDeviationCoefficient (GetDeviationCoeff());
98 myDeflection = Prs3d::GetDeflection (GetShapeObj()->GetShape(), aDefDrawer);
104 //================================================================
105 // Function : meshShape
107 //================================================================
108 void IVtkOCC_ShapeMesher::meshShape()
110 TopoDS_Shape anOcctShape = GetShapeObj()->GetShape();
111 if (anOcctShape.IsNull())
116 //Clean triangulation before compute incremental mesh
117 BRepTools::Clean (anOcctShape);
119 //Compute triangulation
120 Standard_Real aDeflection = GetDeflection();
121 if (aDeflection < Precision::Confusion())
130 Handle(BRepMesh_DiscretRoot) anAlgo;
131 anAlgo = BRepMesh_DiscretFactory::Get().Discret (anOcctShape,
133 GetDeviationAngle());
134 if (!anAlgo.IsNull())
139 catch (Standard_Failure)
143 //================================================================
144 // Function : addFreeVertices
146 //================================================================
147 void IVtkOCC_ShapeMesher::addFreeVertices()
149 TopTools_IndexedDataMapOfShapeListOfShape aVertexMap;
150 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
155 Standard_Integer aVertNum = aVertexMap.Extent();
157 for (Standard_Integer anIt = 1; anIt <= aVertNum; anIt++)
159 if (aVertexMap.FindFromIndex(anIt).IsEmpty())
161 aType = MT_FreeVertex;
165 aType = MT_SharedVertex;
167 TopoDS_Vertex aVertex = TopoDS::Vertex (aVertexMap.FindKey (anIt));
168 addVertex (aVertex, GetShapeObj()->GetSubShapeId (aVertex), aType);
172 //================================================================
173 // Function : addEdges
175 //================================================================
176 void IVtkOCC_ShapeMesher::addEdges()
178 TopTools_IndexedDataMapOfShapeListOfShape anEdgesMap;
179 TopExp::MapShapesAndAncestors (GetShapeObj()->GetShape(),
186 myEdgesTypes.Clear();
188 TopExp_Explorer anEdgeIter (GetShapeObj()->GetShape(), TopAbs_EDGE);
189 for (; anEdgeIter.More(); anEdgeIter.Next())
191 TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current());
192 aNbFaces = anEdgesMap.FindFromKey (anOcctEdge).Extent();
197 else if (aNbFaces == 1)
199 aType = MT_BoundaryEdge;
203 aType = MT_SharedEdge;
205 addEdge (anOcctEdge, GetShapeObj()->GetSubShapeId (anOcctEdge), aType);
206 myEdgesTypes.Bind (anOcctEdge, aType);
210 //================================================================
211 // Function : addWireFrameFaces
213 //================================================================
214 void IVtkOCC_ShapeMesher::addWireFrameFaces()
216 // Check the deflection value once for all faces
217 if (GetDeflection() < Precision::Confusion())
222 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
223 for (; aFaceIter.More(); aFaceIter.Next())
225 TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current());
229 addWFFace (anOcctFace,
230 GetShapeObj()->GetSubShapeId (anOcctFace));
232 catch (Standard_Failure)
237 //================================================================
238 // Function : addShadedFaces
240 //================================================================
241 void IVtkOCC_ShapeMesher::addShadedFaces()
243 TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE);
244 for (; aFaceIter.More(); aFaceIter.Next())
246 TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current());
247 addShadedFace (anOcctFace,
248 GetShapeObj()->GetSubShapeId (anOcctFace));
252 //================================================================
253 // Function : addVertex
255 //================================================================
256 void IVtkOCC_ShapeMesher::addVertex (const TopoDS_Vertex& theVertex,
257 const IVtk_IdType theShapeId,
258 const IVtk_MeshType theMeshType)
260 if (theVertex.IsNull())
265 gp_Pnt aPnt3d = BRep_Tool::Pnt (theVertex);
268 myShapeData->InsertCoordinate (aPnt3d.X(), aPnt3d.Y(), aPnt3d.Z());
269 myShapeData->InsertVertex (theShapeId, anId, theMeshType);
273 //================================================================
274 // Function : processPolyline
276 //================================================================
277 void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer theNbNodes,
278 const TColgp_Array1OfPnt& thePoints,
279 const TColStd_Array1OfInteger& thePointIds,
280 const IVtk_IdType theOcctId,
282 gp_Trsf theTransformation,
283 const IVtk_MeshType theMeshType)
290 IVtk_PointIdList *aPolyPointIds = new IVtk_PointIdList();
293 for (Standard_Integer aJ = 0; aJ < theNbNodes; aJ++)
295 Standard_Integer aPntId = thePointIds (aJ + 1);
296 gp_Pnt point = thePoints (aPntId);
300 // Apply the transformation to points
301 point.Transform (theTransformation);
304 anId = myShapeData->InsertCoordinate (point.X(), point.Y(), point.Z());
305 aPolyPointIds->Append (anId);
308 myShapeData->InsertLine (theOcctId, aPolyPointIds, theMeshType);
310 delete aPolyPointIds;
313 //================================================================
314 // Function : addEdge
316 //================================================================
317 void IVtkOCC_ShapeMesher::addEdge (const TopoDS_Edge& theEdge,
318 const IVtk_IdType theShapeId,
319 const IVtk_MeshType theMeshType)
321 if (theEdge.IsNull() || BRep_Tool::Degenerated (theEdge))
326 // Two discrete representations of an OCCT edge are possible:
327 // 1. Polygon on trinagulation - holds Ids of points
328 // contained in Poly_Triangulation object
329 Handle(Poly_PolygonOnTriangulation) aPolyOnTriangulation;
330 Handle(Poly_Triangulation) aTriangulation;
331 TopLoc_Location aLocation;
332 BRep_Tool::PolygonOnTriangulation (theEdge,
333 aPolyOnTriangulation,
338 // 2. 3D polygon - holds 3D points
339 Handle(Poly_Polygon3D) aPoly3d;
340 if (aPolyOnTriangulation.IsNull())
342 aPoly3d = BRep_Tool::Polygon3D (theEdge, aLocation);
345 if (aPoly3d.IsNull() && aPolyOnTriangulation.IsNull())
350 // Handle a non-identity transofmation applied to the edge
351 gp_Trsf anEdgeTransf;
352 bool noTransform = true;
353 if (!aLocation.IsIdentity())
356 anEdgeTransf = aLocation.Transformation();
359 if (!aPoly3d.IsNull())
361 Standard_Integer aNbNodes = aPoly3d->NbNodes();
362 const TColgp_Array1OfPnt& aPoints = aPoly3d->Nodes();
363 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
365 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
367 aPointIds.SetValue (anI, anI);
370 processPolyline (aNbNodes,
380 Standard_Integer aNbNodes = aPolyOnTriangulation->NbNodes();
381 const TColStd_Array1OfInteger& aPointIds = aPolyOnTriangulation->Nodes();
382 const TColgp_Array1OfPnt& aPoints = aTriangulation->Nodes();
384 processPolyline (aNbNodes,
395 //================================================================
396 // Function : FindLimits
397 // Purpose : Static internal function, finds parametrical limits of the curve.
398 //! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry
399 //! @param [in] theLimit maximum allowed absolute parameter value
400 //! @param [out] theFirst minimum parameter value for the curve
401 //! @param [out] theLast maximum parameter value for the curve
402 //================================================================
403 static void FindLimits (const Adaptor3d_Curve& theCurve,
404 const Standard_Real& theLimit,
405 Standard_Real& theFirst,
406 Standard_Real& theLast)
408 theFirst = Max(theCurve.FirstParameter(), theFirst);
409 theLast = Min(theCurve.LastParameter(), theLast);
410 Standard_Boolean isFirstInf = Precision::IsNegativeInfinite (theFirst);
411 Standard_Boolean isLastInf = Precision::IsPositiveInfinite (theLast);
413 if (isFirstInf || isLastInf)
416 Standard_Real aDelta = 1;
417 if (isFirstInf && isLastInf)
424 theCurve.D0 (theFirst, aP1);
425 theCurve.D0 (theLast, aP2);
426 } while (aP1.Distance (aP2) < theLimit);
430 theCurve.D0 (theLast, aP2);
433 theFirst = theLast - aDelta;
434 theCurve.D0 (theFirst, aP1);
435 } while (aP1.Distance(aP2) < theLimit);
439 theCurve.D0 (theFirst, aP1);
443 theLast = theFirst + aDelta;
444 theCurve.D0 (theLast, aP2);
445 } while (aP1.Distance (aP2) < theLimit);
450 //================================================================
451 // Function : FindLimits
452 // Purpose :Static helper function, builds a discrete representation
453 //! (sequence of points) for the given curve.
455 //! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry
456 //! @param [in] theDeflection absolute deflection value
457 //! @param [in] theAngle deviation angle value
458 //! @param [in] theU1 minimal curve parameter value
459 //! @param [in] theU2 maximal curve parameter value
460 //! @param [out] thePoints the container for generated polyline
461 //================================================================
462 static void DrawCurve (Adaptor3d_Curve& theCurve,
463 const Quantity_Length theDeflection,
464 const Standard_Real theAngle,
465 const Standard_Real theU1,
466 const Standard_Real theU2,
467 IVtk_Polyline& thePoints)
469 switch (theCurve.GetType())
473 gp_Pnt aPnt = theCurve.Value(theU1);
474 thePoints.Append (aPnt);
476 aPnt = theCurve.Value(0.5 * (theU1 + theU2));
477 thePoints.Append (aPnt);
479 aPnt = theCurve.Value (theU2);
480 thePoints.Append(aPnt);
485 Standard_Integer aNbInter = theCurve.NbIntervals(GeomAbs_C1);
486 Standard_Integer anI, aJ;
487 TColStd_Array1OfReal aParams(1, aNbInter+1);
488 theCurve.Intervals(aParams, GeomAbs_C1);
489 Standard_Real anU1, anU2;
490 Standard_Integer NumberOfPoints;
492 for (aJ = 1; aJ <= aNbInter; aJ++)
494 anU1 = aParams (aJ); anU2 = aParams (aJ + 1);
495 if (anU2 > anU1 && anU1 < anU2)
497 anU1 = Max(anU1, anU1);
498 anU2 = Min(anU2, anU2);
500 GCPnts_TangentialDeflection anAlgo (theCurve, anU1, anU2, theAngle, theDeflection);
501 NumberOfPoints = anAlgo.NbPoints();
503 if (NumberOfPoints > 0)
505 for (anI = 1; anI < NumberOfPoints; anI++)
507 thePoints.Append(anAlgo.Value (anI));
511 thePoints.Append (anAlgo.Value (NumberOfPoints));
520 //================================================================
521 // Function : buildIsoLines
523 //================================================================
524 void IVtkOCC_ShapeMesher::buildIsoLines (const Handle(BRepAdaptor_HSurface)& theFace,
525 const Standard_Boolean theIsDrawUIso,
526 const Standard_Boolean theIsDrawVIso,
527 const Standard_Integer theNBUiso,
528 const Standard_Integer theNBViso,
529 IVtk_PolylineList& thePolylines)
531 Standard_Real anUF, anUL, aVF, aVL;
532 anUF = theFace->FirstUParameter();
533 anUL = theFace->LastUParameter();
534 aVF = theFace->FirstVParameter();
535 aVL = theFace->LastVParameter();
537 // Restrict maximal parameter value
538 // in OCCT it's 5e+5 by default
539 const Standard_Real aLimit = 5e+5;
541 // compute bounds of the restriction
542 Standard_Real anUMin, anUMax, aVMin, aVMax;
543 Standard_Integer anI;
545 anUMin = Max (anUF, -aLimit);
546 anUMax = Min (anUL, aLimit);
547 aVMin = Max (aVF, -aLimit);
548 aVMax = Min (aVL, aLimit);
550 // update min max for the hatcher.
554 Standard_Real aDdefle = Max (anUMax - anUMin, aVMax - aVMin) * GetDeviationCoeff();
555 TColgp_SequenceOfPnt2d aTabPoints;
557 anUMin = aVMin = 1.e100;
558 anUMax = aVMax = -1.e100;
561 TopExp_Explorer aToolRst;
562 TopoDS_Face aTopoFace (((BRepAdaptor_Surface*)&(theFace->Surface()))->Face());
563 for (aToolRst.Init (aTopoFace, TopAbs_EDGE); aToolRst.More(); aToolRst.Next())
565 TopAbs_Orientation anOrient = aToolRst.Current().Orientation();
566 // Skip INTERNAL and EXTERNAL edges
567 if (anOrient == TopAbs_FORWARD || anOrient == TopAbs_REVERSED)
569 Standard_Real anU1, anU2;
570 const Handle(Geom2d_Curve)& aCurve =
571 BRep_Tool::CurveOnSurface (TopoDS::Edge (aToolRst.Current()),
579 Geom2dAdaptor_Curve aRCurve;
580 aRCurve.Load (aCurve, anU1, anU2);
581 if (aRCurve.GetType() != GeomAbs_Line)
583 GCPnts_QuasiUniformDeflection aUDP(aRCurve, aDdefle);
586 Standard_Integer NumberOfPoints = aUDP.NbPoints();
587 if ( NumberOfPoints >= 2 )
589 aDummyPnt = aUDP.Value (1);
590 aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y());
591 anUMin = Min (aP2.X(), anUMin);
592 anUMax = Max (aP2.X(), anUMax);
593 aVMin = Min (aP2.Y(), aVMin);
594 aVMax = Max (aP2.Y(), aVMax);
595 for (anI = 2; anI <= NumberOfPoints; anI++)
598 aDummyPnt = aUDP.Value (anI);
599 aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y());
600 anUMin = Min(aP2.X(), anUMin);
601 anUMax = Max(aP2.X(), anUMax);
602 aVMin = Min(aP2.Y(), aVMin);
603 aVMax = Max(aP2.Y(), aVMax);
605 if(anOrient == TopAbs_FORWARD )
607 //isobuild.Trim(P1,P2);
608 aTabPoints.Append (aP1);
609 aTabPoints.Append (aP2);
613 //isobuild.Trim(P2,P1);
614 aTabPoints.Append (aP2);
615 aTabPoints.Append (aP1);
622 cout << "Cannot evaluate curve on surface"<<endl;
627 anU1 = aRCurve.FirstParameter();
628 anU2 = aRCurve.LastParameter();
629 // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
630 // ensure that distance U2-U1 is not greater than aLimit*2,
631 // if greater then choose an origin and use aLimit to define
633 Standard_Real aOrigin = 0.;
634 if (!Precision::IsNegativeInfinite(anU1) || !Precision::IsPositiveInfinite (anU2))
636 if (Precision::IsNegativeInfinite (anU1))
638 aOrigin = anU2 - aLimit;
640 else if (Precision::IsPositiveInfinite (anU2))
642 aOrigin = anU1 + aLimit;
646 aOrigin = (anU1 + anU2) * 0.5;
650 anU1 = Max (aOrigin - aLimit, anU1);
651 anU2 = Min (aOrigin + aLimit, anU2);
652 aP1 = aRCurve.Value (anU1);
653 aP2 = aRCurve.Value (anU2);
654 anUMin = Min(aP1.X(), anUMin);
655 anUMax = Max(aP1.X(), anUMax);
656 aVMin = Min(aP1.Y(), aVMin);
657 aVMax = Max(aP1.Y(), aVMax);
658 anUMin = Min(aP2.X(), anUMin);
659 anUMax = Max(aP2.X(), anUMax);
660 aVMin = Min(aP2.Y(), aVMin);
661 aVMax = Max(aP2.Y(), aVMax);
662 if(anOrient == TopAbs_FORWARD )
664 // isobuild.Trim(P1,P2);
665 aTabPoints.Append (aP1);
666 aTabPoints.Append (aP2);
670 //isobuild.Trim(P2,P1);
671 aTabPoints.Append (aP2);
672 aTabPoints.Append (aP1);
679 const Standard_Real anIntersectionTolerance = 1.e-5;
680 Hatch_Hatcher anIsoBuild (anIntersectionTolerance, Standard_True );
682 Standard_Boolean isUClosed = theFace->IsUClosed();
683 Standard_Boolean isVClosed = theFace->IsVClosed();
687 anUMin = anUMin + (anUMax - anUMin) / 1000.0;
688 anUMax = anUMax - (anUMax - anUMin) /1000.0;
693 aVMin = aVMin + (aVMax - aVMin) /1000.0;
694 aVMax = aVMax - (aVMax - aVMin) /1000.0;
701 isUClosed = Standard_False;
702 Standard_Real aDu= isUClosed ? (anUMax - anUMin) / theNBUiso : (anUMax - anUMin) / (1 + theNBUiso);
703 for (anI = 1; anI <= theNBUiso; anI++)
705 anIsoBuild.AddXLine (anUMin + aDu*anI);
713 isVClosed = Standard_False;
714 Standard_Real aDv= isVClosed ? (aVMax - aVMin) / theNBViso : (aVMax - aVMin) / (1 + theNBViso);
715 for (anI = 1; anI <= theNBViso; anI++)
717 anIsoBuild.AddYLine (aVMin + aDv*anI);
722 Standard_Integer aLength = aTabPoints.Length();
723 for (anI = 1; anI <= aLength; anI += 2)
725 anIsoBuild.Trim (aTabPoints (anI),aTabPoints (anI + 1));
728 // Create the polylines for isos
729 Adaptor3d_IsoCurve anIso;
731 Handle(Geom_Curve) aBCurve;
732 const BRepAdaptor_Surface& aBSurf = *(BRepAdaptor_Surface*)&(theFace->Surface());
733 GeomAbs_SurfaceType aType = theFace->GetType();
735 Standard_Integer aNumberOfLines = anIsoBuild.NbLines();
736 Handle(Geom_Surface) aGeomSurf;
737 if (aType == GeomAbs_BezierSurface)
739 aGeomSurf = aBSurf.Bezier();
741 else if (aType == GeomAbs_BSplineSurface)
743 aGeomSurf = aBSurf.BSpline();
746 Standard_Real aDeflection = GetDeflection();
747 Standard_Real anAngle = GetDeviationAngle();
748 for (anI = 1; anI <= aNumberOfLines; anI++)
750 Standard_Integer aNumberOfIntervals = anIsoBuild.NbIntervals(anI);
751 Standard_Real aCoord = anIsoBuild.Coordinate(anI);
752 for (Standard_Integer aJ = 1; aJ <= aNumberOfIntervals; aJ++)
754 Standard_Real aB1 = anIsoBuild.Start (anI, aJ);
755 Standard_Real aB2 = anIsoBuild.End(anI, aJ);
757 if (!aGeomSurf.IsNull())
759 if (anIsoBuild.IsXLine (anI))
761 aBCurve = aGeomSurf->UIso (aCoord);
765 aBCurve = aGeomSurf->VIso (aCoord);
768 GeomAdaptor_Curve aGeomCurve (aBCurve);
769 FindLimits (aGeomCurve, aLimit, aB1, aB2);
770 if (aB2 - aB1 > Precision::Confusion())
772 IVtk_Polyline aPoints;
773 DrawCurve (aGeomCurve, aDeflection, anAngle, aB1, aB2, aPoints);
774 thePolylines.Append (aPoints);
779 if (anIsoBuild.IsXLine (anI))
781 anIso.Load (GeomAbs_IsoU, aCoord, aB1, aB2);
785 anIso.Load (GeomAbs_IsoV, aCoord, aB1, aB2);
787 FindLimits (anIso, aLimit, aB1, aB2);
788 if (aB2 - aB1>Precision::Confusion())
790 IVtk_Polyline aPoints;
791 DrawCurve (anIso, aDeflection, anAngle, aB1, aB2, aPoints);
792 thePolylines.Append (aPoints);
799 //================================================================
800 // Function : addWFFace
802 //================================================================
803 void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace,
804 const IVtk_IdType theShapeId)
806 if (theFace.IsNull())
811 TopoDS_Face aFaceToMesh = theFace;
812 aFaceToMesh.Orientation (TopAbs_FORWARD);
814 // The code that builds wireframe representation for a TopoDS_Face
815 // has been adapted from some OCCT 6.5.1 methods:
816 // - Prs3d_WFShape::Add()
817 // - StdPrs_WFDeflectionRestrictedFace::Add()
818 // - StdPrs_DeflectionCurve::Add()
820 // Add face's edges here but with the face ID
821 TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE );
822 for (; anEdgeIter.More(); anEdgeIter.Next())
824 TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current());
825 addEdge (anOcctEdge, theShapeId, myEdgesTypes (anOcctEdge));
828 TopLoc_Location aLoc;
829 const Handle(Geom_Surface)& aGeomSurf = BRep_Tool::Surface (aFaceToMesh, aLoc);
830 if (aGeomSurf.IsNull())
835 BRepAdaptor_Surface aSurf;
836 aSurf.Initialize (aFaceToMesh);
837 Handle(BRepAdaptor_HSurface) aSurfAdaptor = new BRepAdaptor_HSurface (aSurf);
839 IVtk_PolylineList aPolylines;
842 // Building U isolines
843 // Introducing a local scope here to simplify variable naming
845 buildIsoLines (aSurfAdaptor,
852 IVtk_PolylineList::Iterator anIt (aPolylines);
853 for (; anIt.More(); anIt.Next())
855 const IVtk_Polyline& aPntSeq = anIt.Value();
856 Standard_Integer aNbNodes = aPntSeq.Length();
857 TColgp_Array1OfPnt aPoints (1, aNbNodes);
858 for (Standard_Integer aJ = 1; aJ <= aNbNodes; aJ++)
860 aPoints.SetValue (aJ, aPntSeq.Value(aJ));
863 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
864 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
866 aPointIds.SetValue (anI, anI);
869 processPolyline (aNbNodes,
879 // Building V isolines
882 buildIsoLines (aSurfAdaptor,
889 IVtk_PolylineList::Iterator anIt (aPolylines);
890 for (; anIt.More(); anIt.Next())
892 const IVtk_Polyline& aPntSeq = anIt.Value();
893 Standard_Integer aNbNodes = aPntSeq.Length();
894 TColgp_Array1OfPnt aPoints (1, aNbNodes);
895 for (int aJ = 1; aJ <= aNbNodes; aJ++)
897 aPoints.SetValue (aJ, aPntSeq.Value (aJ));
900 TColStd_Array1OfInteger aPointIds (1, aNbNodes);
901 for (Standard_Integer anI = 1; anI <= aNbNodes; anI++)
903 aPointIds.SetValue (anI, anI);
906 processPolyline (aNbNodes,
917 //================================================================
918 // Function : addShadedFace
920 //================================================================
921 void IVtkOCC_ShapeMesher::addShadedFace (const TopoDS_Face& theFace,
922 const IVtk_IdType theShapeId)
924 if (theFace.IsNull())
929 // Build triangulation of the face.
930 TopLoc_Location aLoc;
931 Handle(Poly_Triangulation) anOcctTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
932 if (anOcctTriangulation.IsNull())
937 gp_Trsf aPntTransform;
938 Standard_Boolean noTransform = Standard_True;
939 if (!aLoc.IsIdentity())
941 noTransform = Standard_False;
942 aPntTransform = aLoc.Transformation();
945 // Get triangulation points.
946 const TColgp_Array1OfPnt& aPoints = anOcctTriangulation->Nodes();
947 Standard_Integer aNbPoints = anOcctTriangulation->NbNodes();
949 // Keep inserted points id's of triangulation in an array.
950 NCollection_Array1<IVtk_PointId> aPointIds (1, aNbPoints);
953 Standard_Integer anI;
954 for (anI = 1; anI <= aNbPoints; anI++)
956 gp_Pnt aPoint = aPoints (anI);
960 aPoint.Transform (aPntTransform);
963 // Add a point into output shape data and keep its id in the array.
964 anId = myShapeData->InsertCoordinate (aPoint.X(), aPoint.Y(), aPoint.Z());
965 aPointIds.SetValue (anI, anId);
968 // Create triangles on the created triangulation points.
969 const Poly_Array1OfTriangle& aTriangles = anOcctTriangulation->Triangles();
970 Standard_Integer aNbTriangles = anOcctTriangulation->NbTriangles();
971 Standard_Integer aN1, aN2, aN3;
972 for (anI = 1; anI <= aNbTriangles; anI++)
974 aTriangles(anI).Get (aN1, aN2, aN3); // get indexes of triangle's points
975 // Insert new triangle on these points into output shape data.
976 myShapeData->InsertTriangle (
977 theShapeId, aPointIds(aN1), aPointIds(aN2), aPointIds(aN3), MT_ShadedFace);