-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015 EDF-R&D
// 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
//
#include <HYDROGUI_Polyline.h>
-
-#include <AIS_InteractiveContext.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBndLib.hxx>
#include <BRep_Tool.hxx>
#include <GCPnts_AbscissaPoint.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Dir.hxx>
+#include <GCPnts_QuasiUniformDeflection.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Prs3d_Arrow.hxx>
-#include <TopExp.hxx>
-#include <TopoDS_Shape.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_Point.hxx>
+#include <Prs3d_Root.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
-#include <BRepBndLib.hxx>
-#include <Precision.hxx>
-IMPLEMENT_STANDARD_HANDLE (HYDROGUI_Polyline, AIS_Shape)
IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Polyline, AIS_Shape)
{
}
+Handle( Graphic3d_ArrayOfPolylines ) BuildEdgePresentation( const TopoDS_Edge& theEdge, double theDeviation )
+{
+ BRepAdaptor_Curve aCurveAdaptor( theEdge );
+ GCPnts_QuasiUniformDeflection aPnts( aCurveAdaptor, theDeviation );
+
+ Handle( Graphic3d_ArrayOfPolylines ) anArray;
+ if( !aPnts.IsDone() )
+ return anArray;
+
+ int n = aPnts.NbPoints();
+ anArray = new Graphic3d_ArrayOfPolylines( n );
+ for( int i=1; i<=n; i++ )
+ anArray->AddVertex( aPnts.Value( i ) );
+
+ return anArray;
+}
+
void HYDROGUI_Polyline::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
const Handle(Prs3d_Presentation)& aPrs,
const Standard_Integer aMode)
{
- AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
-
- TopExp_Explorer Exp ( myshape, TopAbs_EDGE );
- for ( ; Exp.More(); Exp.Next() ) {
- TopoDS_Vertex aV1, aV2;
- TopoDS_Edge anEdge = TopoDS::Edge(Exp.Current());
-
- if ( anEdge.IsNull() )
- continue;
- TopExp::Vertices(anEdge, aV1, aV2);
- gp_Pnt aP = BRep_Tool::Pnt(aV1);
- gp_Vec aDirVec;
- double aFp, aLp;
- Handle(Geom_Curve) C = BRep_Tool::Curve(anEdge,aFp,aLp);
- if ( C.IsNull() )
- continue;
-
- Bnd_Box aBB;
- BRepBndLib::Add(anEdge, aBB);
- Standard_Real aXmin,aYmin,aZmin,aXmax,aYmax,aZmax;
- aBB.Get(aXmin,aYmin,aZmin,aXmax,aYmax,aZmax);
- Standard_Real aLen = Max(Abs(aXmax - aXmin), Max (Abs(aZmax - aZmin), Abs(aYmax - aYmin)));
-
- GeomAdaptor_Curve aAdC;
- aAdC.Load(C, aFp, aLp);
- double aLenC;
- double aLenH;
- int aNbSegments = 20;
- double aArrLen = aLen / 10.;
- double anIncr = (aLp-aFp)/aNbSegments;
- double aMaxRatio = 0;
- double aMaxRatioStep = 1;
- for (double t = aFp; t < aLp - anIncr; t += anIncr)
+ //AIS_Shape::Compute(aPresentationManager, aPrs, aMode);
+ //return;
+
+ aPrs->Clear();
+ Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
+ Quantity_Color aColor;
+ Aspect_TypeOfLine aType;
+ Standard_Real anWidth;
+ Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
+ anWidth =2;
+ Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
+
+ TopExp_Explorer Exp1 ( myshape, TopAbs_EDGE );
+ Bnd_Box BB;
+ BRepBndLib::AddClose(myshape, BB);
+ double xmin, xmax, ymin, ymax, zmin, zmax;
+ double devCoeff = 0.05;
+ if (!BB.IsVoid())
+ {
+ BB.Get(xmin, ymin, zmin, xmax, ymax, zmax); //ignore Z coord
+ double minSide = Min(Abs(xmax - xmin), Abs(ymax - ymin));
+ devCoeff = minSide > 50 ? 0.05 : minSide / 3000;
+ }
+ for ( ; Exp1.More(); Exp1.Next() )
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge( Exp1.Current() );
+ Handle( Graphic3d_ArrayOfPolylines ) anArray = BuildEdgePresentation( anEdge, devCoeff );
+ if( !anArray.IsNull() )
{
- aLenC = GCPnts_AbscissaPoint::Length(aAdC, t, t + anIncr);
- aLenH = C->Value (t).Distance (C->Value (t + anIncr));
- if ( aLenH / aLenC > aMaxRatio) {
- aMaxRatio = aLenH / aLenC;
- aMaxRatioStep = t;
- }
+ aGroup->SetPrimitivesAspect( anAspect );
+ aGroup->AddPrimitiveArray( anArray );
}
+ }
+}
+
+QList<Handle(AIS_InteractiveObject)> HYDROGUI_Polyline::createPresentations
+ ( const TopoDS_Shape& theShape, int theType, int theSize )
+{
+ QList<Handle(AIS_InteractiveObject)> shapes;
+
+ // 1. Main shape
+ shapes.append( new HYDROGUI_Polyline( theShape ) );
- bool UseD1 = false;
- if (Abs(aMaxRatioStep) < Precision::Confusion())
+ // 2. Shapes for direction arrows on edges
+ TopExp_Explorer Exp ( theShape, TopAbs_EDGE );
+ for ( ; Exp.More(); Exp.Next() )
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge(Exp.Current());
+ if ( !anEdge.IsNull() )
{
- aMaxRatioStep = (aLp - aFp)/2.0;
- UseD1 = true;
+ Handle(HYDROGUI_Arrow) arrow = new HYDROGUI_Arrow( anEdge );
+ if( theType>=0 )
+ arrow->SetType( (HYDROGUI_Arrow::Type)theType );
+ if( theSize>=0 )
+ arrow->SetSize( theSize );
+ shapes.append( arrow );
}
+ }
+
+ return shapes;
+}
- if (Abs(aLp - aMaxRatioStep) < Precision::Confusion())
+void HYDROGUI_Polyline::update( const QList<Handle(AIS_InteractiveObject)>& theObjects, int theType, int theSize )
+{
+ foreach( Handle(AIS_InteractiveObject) obj, theObjects )
+ {
+ Handle(HYDROGUI_Arrow) arrow = Handle(HYDROGUI_Arrow)::DownCast( obj );
+ if( !arrow.IsNull() )
{
- aMaxRatioStep = (aLp - aFp)/2.0;
- UseD1 = true;
- }
-
- gp_Pnt aPnt1 = C->Value (aMaxRatioStep);
- gp_Vec aDir;
- if (!UseD1) {
- GCPnts_AbscissaPoint aAbsPoint(aAdC, -aArrLen, aMaxRatioStep);
- double aParam = aAbsPoint.Parameter();
- gp_Pnt aPnt2 = C->Value (aParam);
- gp_XYZ D = aPnt1.XYZ();
- D.Subtract (aPnt2.XYZ());
- aDir = D;
+ if( theType>=0 )
+ arrow->SetType( (HYDROGUI_Arrow::Type)theType );
+ if( theSize>=0 )
+ arrow->SetSize( theSize );
}
- else
- C->D1(aMaxRatioStep, C->Value (aMaxRatioStep), aDir);
-
- if ( anEdge.Orientation() == TopAbs_REVERSED )
- aDir = -aDir;
+ }
+}
+
+
+
+
+IMPLEMENT_STANDARD_RTTIEXT(HYDROGUI_Arrow, AIS_Shape)
+
+
+HYDROGUI_Arrow::HYDROGUI_Arrow( const TopoDS_Edge& edge )
+ : AIS_Shape( edge ), myType( Cone ), mySize( 35 )
+{
+}
+
+HYDROGUI_Arrow::~HYDROGUI_Arrow()
+{
+}
+
+HYDROGUI_Arrow::Type HYDROGUI_Arrow::GetType() const
+{
+ return myType;
+}
+
+void HYDROGUI_Arrow::SetType( HYDROGUI_Arrow::Type theType )
+{
+ myType = theType;
+}
+
+int HYDROGUI_Arrow::GetSize() const
+{
+ return mySize;
+}
+
+void HYDROGUI_Arrow::SetSize( int theSize )
+{
+ mySize = qMax( theSize, 0 );
+}
+
+void HYDROGUI_Arrow::Compute( const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
+ const Handle(Prs3d_Presentation)& aPrs,
+ const Standard_Integer aMode )
+{
+ aPrs->Clear();
+ if( myType==None )
+ return;
- Prs3d_Arrow::Draw(aPrs, aPnt1, aDir, M_PI/180.*12., aArrLen);
+ TopoDS_Edge anEdge = TopoDS::Edge( myshape );
+ if( anEdge.IsNull() )
+ return;
+
+ BRepAdaptor_Curve anAdaptor( anEdge );
+ double curveLen = GCPnts_AbscissaPoint::Length( anAdaptor, anAdaptor.FirstParameter(), anAdaptor.LastParameter() );
+ double arrowLen;
+ if( mySize==0 )
+ // if size==0, then the arrow length is proportional to curve length
+ arrowLen = curveLen/10;
+ else
+ arrowLen = qMin( curveLen/10, (double)mySize );
+
+ double t = ( anAdaptor.FirstParameter() + anAdaptor.LastParameter() ) / 2;
+ gp_Pnt P, P1;
+ gp_Vec V;
+ anAdaptor.D1( t, P, V );
+
+ bool isFixed = mySize>0;
+
+ if( isFixed )
+ {
+ gp_Trsf tr;
+ tr.SetTranslation( -gp_Vec( gp_Pnt(), P ) );
+ aPrs->SetTransformation( new Geom_Transformation( tr ) );
+
+ Handle(Graphic3d_TransformPers) tp = new Graphic3d_TransformPers( Graphic3d_TMF_ZoomPers, P );
+ SetTransformPersistence( tp );
+
+ P1 = gp_Pnt();
+ }
+ else
+ P1 = P;
+
+ Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup( aPrs );
+ Quantity_Color aColor;
+ Aspect_TypeOfLine aType;
+ Standard_Real anWidth;
+ Attributes()->LineAspect()->Aspect()->Values( aColor, aType, anWidth );
+ anWidth = 1;
+
+ if( myType==Cone )
+ {
+ Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d( aColor, aType, anWidth );
+ aGroup->SetPrimitivesAspect( anAspect );
+
+ Prs3d_Arrow::Draw( aGroup, P1, V, M_PI/180.*12., arrowLen );
+ }
+ else
+ {
+ Graphic3d_MaterialAspect m( Graphic3d_NOM_PLASTIC );
+ Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d
+ ( Aspect_IS_SOLID, aColor, aColor, Aspect_TOL_SOLID, 1, m, m );
+ aGroup->SetPrimitivesAspect( anAspect );
+
+ gp_Vec d = -V.Normalized() * arrowLen;
+ const double k = 5.0;
+ gp_Vec n( -d.Y()/k, d.X()/k, 0 );
+
+ gp_Pnt Pa = P1.Translated( d );
+ gp_Pnt P2 = Pa.Translated( n );
+ gp_Pnt P3 = Pa.Translated( -n );
+
+ Handle(Graphic3d_ArrayOfTriangles) prim = new Graphic3d_ArrayOfTriangles(3);
+ prim->AddVertex( P1 );
+ prim->AddVertex( P2 );
+ prim->AddVertex( P3 );
+
+ aGroup->AddPrimitiveArray( prim );
}
}