// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "GEOM_EdgeSource.h" #include #include #include #include #include #include #include #include #include #include #include #include vtkStandardNewMacro(GEOM_EdgeSource); GEOM_EdgeSource::GEOM_EdgeSource() : myIsVector(false) { } GEOM_EdgeSource::~GEOM_EdgeSource() { } void GEOM_EdgeSource::AddEdge (const TopoDS_Edge& theEdge, bool theIsVector) { myEdgeSet.Add(theEdge); myIsVector = theIsVector; } void GEOM_EdgeSource:: Execute() { vtkPolyData* aPolyData = GetOutput(); aPolyData->Allocate(); vtkPoints* aPts = vtkPoints::New(); aPolyData->SetPoints(aPts); aPts->Delete(); TEdgeSet::Iterator anIter (myEdgeSet); for (; anIter.More(); anIter.Next()) { TopoDS_Edge anEdge = anIter.Value(); if ( !myIsVector ) // draw curve direction (issue 0021087) anEdge.Orientation( TopAbs_FORWARD ); OCC2VTK(anEdge,aPolyData,aPts,myIsVector||myIsVectorMode); } } void GEOM_EdgeSource::OCC2VTK (const TopoDS_Edge& theEdge, vtkPolyData* thePolyData, vtkPoints* thePts, bool theIsVector) { Handle(Poly_PolygonOnTriangulation) aEdgePoly; Standard_Integer i = 1; Handle(Poly_Triangulation) T; TopLoc_Location aEdgeLoc; BRep_Tool::PolygonOnTriangulation(theEdge, aEdgePoly, T, aEdgeLoc, i); Handle(Poly_Polygon3D) P; if(aEdgePoly.IsNull()) P = BRep_Tool::Polygon3D(theEdge, aEdgeLoc); if(P.IsNull() && aEdgePoly.IsNull()) return; // Location edges //--------------- gp_Trsf edgeTransf; Standard_Boolean isidtrsf = true; if(!aEdgeLoc.IsIdentity()) { isidtrsf = false; edgeTransf = aEdgeLoc.Transformation(); } gp_Pnt aP1, aP2; if (aEdgePoly.IsNull()) { Standard_Integer aNbNodes = P->NbNodes(); const TColgp_Array1OfPnt& aNodesP = P->Nodes(); aP1 = aNodesP(1); aP2 = aNodesP(aNbNodes); for (int j = 1; j < aNbNodes; j++) { gp_Pnt pt1 = aNodesP(j); gp_Pnt pt2 = aNodesP(j+1); if (!isidtrsf) { // apply edge transformation pt1.Transform(edgeTransf); pt2.Transform(edgeTransf); } float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()}; vtkIdType anIds[2]; anIds[0] = thePts->InsertNextPoint(aCoord1); float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()}; anIds[1] = thePts->InsertNextPoint(aCoord2); thePolyData->InsertNextCell(VTK_LINE,2,anIds); } } else { Standard_Integer aNbNodes = aEdgePoly->NbNodes(); const TColStd_Array1OfInteger& aNodeIds = aEdgePoly->Nodes(); const TColgp_Array1OfPnt& anId2Pnts = T->Nodes(); aP1 = anId2Pnts(aNodeIds(1)); aP2 = anId2Pnts(aNodeIds(aNbNodes)); for(int j = 1; j < aNbNodes; j++) { Standard_Integer id1 = aNodeIds(j); Standard_Integer id2 = aNodeIds(j+1); gp_Pnt pt1 = anId2Pnts(id1); gp_Pnt pt2 = anId2Pnts(id2); if(!isidtrsf) { // apply edge transformation pt1.Transform(edgeTransf); pt2.Transform(edgeTransf); } float aCoord1[3] = {pt1.X(), pt1.Y(), pt1.Z()}; vtkIdType anIds[2]; anIds[0] = thePts->InsertNextPoint(aCoord1); float aCoord2[3] = {pt2.X(), pt2.Y(), pt2.Z()}; anIds[1] = thePts->InsertNextPoint(aCoord2); thePolyData->InsertNextCell(VTK_LINE,2,anIds); } } // vector representation has an arrow on its end if (theIsVector) { if (!isidtrsf) { // apply edge transformation aP1.Transform(edgeTransf); aP2.Transform(edgeTransf); } // draw an arrow double fp,lp; gp_Vec aDirVec; Handle(Geom_Curve) C = BRep_Tool::Curve(theEdge,fp,lp); if ( theEdge.Orientation() == TopAbs_FORWARD ) { C->D1(lp, aP2, aDirVec); } else { C->D1(fp, aP1, aDirVec); aP2 = aP1; } GeomAdaptor_Curve aAdC; aAdC.Load(C, fp, lp); Standard_Real aDist = GCPnts_AbscissaPoint::Length(aAdC, fp, lp); if (aDist < gp::Resolution()) return; gp_Dir aDirection; if ( theEdge.Orientation() == TopAbs_FORWARD ) aDirection = aDirVec; else aDirection = -aDirVec; Standard_Real anAngle = PI/180.*5.; Standard_Real aLength = aDist/10.; Standard_Real dx,dy,dz; aDirection.Coord(dx,dy,dz); // Arrow Point Standard_Real xo,yo,zo; aP2.Coord(xo,yo,zo); // Center of circle that arrow based gp_XYZ aPc = aP2.XYZ() - aDirection.XYZ() * aLength; // Construction of the base vectors for the arrow circle gp_Dir aDirN; if (Abs(dx) <= Abs(dy) && Abs(dx) <= Abs(dz)) aDirN = gp::DX(); else if (Abs(dy) <= Abs(dz) && Abs(dy) <= Abs(dx)) aDirN = gp::DY(); else aDirN = gp::DZ(); gp_Dir aDirI = aDirection ^ aDirN; gp_Dir aDirJ = aDirection ^ aDirI; // Add points and segments, composing the arrow Standard_Real cosinus, sinus, Tg = tan(anAngle); float coord[3] = {xo, yo, zo}; vtkIdType ptLoc = thePts->InsertNextPoint(coord); vtkIdType ptFirst = 0; vtkIdType ptPrev = 0; vtkIdType ptCur = 0; vtkIdType pts[2]; int NbPoints = 15; for (int i = 1; i <= NbPoints; i++, ptPrev = ptCur) { cosinus = cos(2. * PI / NbPoints * (i-1)); sinus = sin(2. * PI / NbPoints * (i-1)); gp_XYZ aP = aPc + (aDirI.XYZ() * cosinus + aDirJ.XYZ() * sinus) * aLength * Tg; coord[0] = aP.X(); coord[1] = aP.Y(); coord[2] = aP.Z(); // insert pts ptCur = thePts->InsertNextPoint(coord); pts[0] = ptCur; if (i == 1) { ptFirst = ptCur; } else { // insert line (ptCur,ptPrev) pts[1] = ptPrev; thePolyData->InsertNextCell(VTK_LINE,2,pts); } // insert line (ptCur,ptLoc) pts[1] = ptLoc; thePolyData->InsertNextCell(VTK_LINE,2,pts); } // insert line (ptCur,ptFirst) pts[0] = ptCur; pts[1] = ptFirst; thePolyData->InsertNextCell(VTK_LINE,2,pts); } } void GEOM_EdgeSource::SetVectorMode (bool theMode) { myIsVectorMode = theMode; } bool GEOM_EdgeSource::GetVectorMode () { return !myIsVector && myIsVectorMode; }