-// Copyright (C) 2013 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013-2016 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.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "CurveCreator_Utils.hxx"
#include "CurveCreator.hxx"
#include "CurveCreator_Curve.hxx"
+#include "CurveCreator_Section.hxx"
#include "CurveCreator_UtilsICurve.hxx"
+#include <Basics_OCCTVersion.hxx>
+
#include <GEOMUtils.hxx>
#include <gp_Pln.hxx>
return ResultPoint;
}
-void CurveCreator_Utils::constructShape( const CurveCreator_ICurve* theCurve,
- TopoDS_Shape& theShape )
+//=======================================================================
+// function : constructBSpline
+// purpose :
+//=======================================================================
+bool CurveCreator_Utils::constructBSpline(
+ const Handle(TColgp_HArray1OfPnt)& thePoints,
+ const Standard_Boolean theIsClosed,
+ Handle(Geom_BSplineCurve)& theBSpline)
{
- BRep_Builder aBuilder;
- TopoDS_Compound aComp;
- aBuilder.MakeCompound( aComp );
- for( int iSection = 0 ; iSection < theCurve->getNbSections() ; iSection++ )
+ const int aPointCount = thePoints->Length();
+ if (aPointCount <= 1)
{
- int theISection = iSection;
+ return false;
+ }
- CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection );
- int aPointSize = theCurve->getNbPoints( theISection );
- if ( aPointSize == 0 )
- continue;
+ // Calculate the tangents.
+ TColgp_Array1OfVec aTangents(1, aPointCount);
+ Handle(TColStd_HArray1OfBoolean) aTangentFlags =
+ new TColStd_HArray1OfBoolean(1, aPointCount);
+ GeomAPI_Interpolate aInterpolator(thePoints, theIsClosed, 0);
+ if (aPointCount == 2)
+ {
+ aTangentFlags->SetValue(1, Standard_False);
+ aTangentFlags->SetValue(2, Standard_False);
+ }
+ else
+ {
+ for (Standard_Integer aPN = 1; aPN <= aPointCount; ++aPN)
+ {
+ gp_Vec aTangent;
+ if (aPN != 1 || theIsClosed)
+ {
+ const Standard_Integer aPN1 = (aPN != 1) ? (aPN - 1) : aPointCount;
+ aTangent = gp_Vec(thePoints->Value(aPN1),
+ thePoints->Value(aPN)).Normalized();
+ }
+ if (aPN < aPointCount || theIsClosed)
+ {
+ const Standard_Integer aPN2 = (aPN != aPointCount) ? (aPN + 1) : 1;
+ const gp_Vec aTangent2 = aTangent +
+ gp_Vec(thePoints->Value(aPN), thePoints->Value(aPN2)).Normalized();
+ if (aTangent2.SquareMagnitude() >= Precision::SquareConfusion())
+ {
+ aTangent = aTangent2.Normalized();
+ }
+ else
+ {
+ aTangent = -aTangent;
+ }
+ }
+ aTangents.SetValue(aPN, aTangent);
+ aTangentFlags->SetValue(aPN, Standard_True);
+ }
+ }
- bool aSectIsClosed = theCurve->isClosed( theISection );
- bool isPolyline = aSectType == CurveCreator::Polyline;
-
- int iPoint = 0;
- gp_Pnt aPrevPoint, aPoint;
- // filters the curve points to skip equal points
- std::vector<gp_Pnt> aPoints;
- CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint );
- aPoints.push_back( aPoint );
- aPrevPoint = aPoint;
- iPoint++;
- for( ; iPoint < aPointSize; iPoint++ ) {
- CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint );
- if ( !isEqualPoints( aPrevPoint, aPoint ) )
- aPoints.push_back( aPoint );
- aPrevPoint = aPoint;
+ // Interpolate.
+ aInterpolator.Load(aTangents, aTangentFlags, Standard_False);
+ aInterpolator.Perform();
+ const bool aResult = (aInterpolator.IsDone() == Standard_True);
+ if (aResult)
+ {
+ theBSpline = aInterpolator.Curve();
+ }
+ return aResult;
+}
+
+//=======================================================================
+// function : constructWire
+// purpose :
+//=======================================================================
+TopoDS_Wire CurveCreator_Utils::ConstructWire(
+ Handle(TColgp_HArray1OfPnt) thePoints,
+ const bool theIsPolyline,
+ const bool theIsClosed)
+{
+ TopoDS_Wire aWire;
+ BRep_Builder aBuilder;
+ aBuilder.MakeWire(aWire);
+ const int aPointCount = thePoints->Length();
+ if (theIsPolyline)
+ {
+ const TopoDS_Vertex aFirstVertex =
+ BRepBuilderAPI_MakeVertex(thePoints->Value(1));
+ TopoDS_Vertex aVertex = aFirstVertex;
+ for (Standard_Integer aPN = 1; aPN < aPointCount; ++aPN)
+ {
+ const TopoDS_Vertex aVertex2 =
+ BRepBuilderAPI_MakeVertex(thePoints->Value(aPN + 1));
+ aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aVertex, aVertex2));
+ aVertex = aVertex2;
+ }
+ if (theIsClosed && aPointCount > 1)
+ {
+ aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aVertex, aFirstVertex));
+ }
+ }
+ else
+ {
+ Handle(Geom_BSplineCurve) aBSpline;
+ if (constructBSpline(thePoints, theIsClosed, aBSpline))
+ {
+ aBuilder.Add(aWire, BRepBuilderAPI_MakeEdge(aBSpline));
}
- int aNbPoints = aPoints.size();
+ }
+ return aWire;
+}
- if ( aNbPoints == 1 ) {
- aPoint = aPoints.front();
- TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
- aBuilder.Add( aComp, aVertex );
+//=======================================================================
+// function : constructShape
+// purpose :
+//=======================================================================
+void CurveCreator_Utils::constructShape(
+ const CurveCreator_ICurve* theCurve, TopoDS_Shape& theShape)
+{
+ BRep_Builder aBuilder;
+ TopoDS_Compound aShape;
+ aBuilder.MakeCompound(aShape);
+ const int aSectionCount = theCurve->getNbSections();
+ for (int aSectionI = 0; aSectionI < aSectionCount; ++aSectionI)
+ {
+ const int aTmpPointCount = theCurve->getNbPoints(aSectionI);
+ if (aTmpPointCount == 0)
+ {
+ continue;
}
- else if ( aNbPoints > 1 ) {
- Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt(1, aNbPoints);
- TColgp_Array1OfVec aTangents(1, aNbPoints);
- Handle(TColStd_HArray1OfBoolean) aTangentFlags = new TColStd_HArray1OfBoolean(1, aNbPoints);
- gp_Vec aNullVec(0, 0, 0);
-
- TopoDS_Edge aPointEdge;
- TopoDS_Vertex aVertex;
-
- std::vector<gp_Pnt>::const_iterator aPointIt = aPoints.begin(), aPointLast = aPoints.end();
- aPoint = *aPointIt;
-
- int aHIndex = 1;
- aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
- aBuilder.Add( aComp, aVertex );
- if ( !isPolyline ) {
- aHCurvePoints->SetValue( aHIndex, aPoint );
- aTangents.SetValue( aHIndex, aNullVec );
- aTangentFlags->SetValue( aHIndex, Standard_False );
- aHIndex++;
- }
- aPrevPoint = aPoint;
- aPointIt++;
- for( ; aPointIt != aPointLast; aPointIt++ ) {
- aPoint = *aPointIt;
- aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
- aBuilder.Add( aComp, aVertex );
- if ( isPolyline ) {
- TopoDS_Edge aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge();
- aBuilder.Add( aComp, aPointEdge );
- }
- else {
- aHCurvePoints->SetValue( aHIndex, aPoint );
- aTangents.SetValue( aHIndex, aNullVec );
- aTangentFlags->SetValue( aHIndex, Standard_False );
- aHIndex++;
- }
- aPrevPoint = aPoint;
- }
- if( aSectIsClosed && ( aNbPoints > 2 ) ) {
- aPoint = aPoints.front();
- aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
- aBuilder.Add( aComp, aVertex );
- if ( isPolyline ) {
- aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge();
- aBuilder.Add( aComp, aPointEdge );
- }
- }
- if( !isPolyline ) {
- // compute BSpline
- Handle(Geom_BSplineCurve) aBSplineCurve;
- GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution());
- // correct the spline degree to be as 3 for non-periodic spline if number of points
- // less than 3. It is need to have a knot in each spline point. This knots are used
- // to found a neighbour points when a new point is inserted between two existing.
- if (!aSectIsClosed ) {
- if (aHCurvePoints->Length() == 3)
- aGBC.Load(aTangents, aTangentFlags);
- }
+ // Get the different points.
+ const CurveCreator_ISection* aSection = theCurve->getSection(aSectionI);
+ Handle(TColgp_HArray1OfPnt) aPoints;
+ aSection->GetDifferentPoints(theCurve->getDimension(), aPoints);
+ const int aPointCount = aPoints->Length();
+ const bool isClosed = theCurve->isClosed(aSectionI);
- aGBC.Perform();
- if ( aGBC.IsDone() )
- aBSplineCurve = aGBC.Curve();
- TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge();
- TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire();
- aBuilder.Add( aComp, aWire );
- }
+ // Add the vertices to the shape.
+ for (Standard_Integer aPN = 1; aPN <= aPointCount; ++aPN)
+ {
+ aBuilder.Add(aShape, BRepBuilderAPI_MakeVertex(aPoints->Value(aPN)));
+ }
+
+ // Add the wire to the shape.
+ const bool isPolyline =
+ (theCurve->getSectionType(aSectionI) == CurveCreator::Polyline);
+ const TopoDS_Wire aWire = ConstructWire(aPoints, isPolyline, isClosed);
+ if (!aWire.IsNull())
+ {
+ aBuilder.Add(aShape, aWire);
}
}
- theShape = aComp;
+ theShape = aShape;
}
/**
{
thePoints.clear();
- std::list<float> aSelectedPoints;
+ std::list<double> aSelectedPoints;
gp_Pnt aPnt;
std::map<CompareSectionToPoint, int> aPointsMap;
//ASL: we switch off automatic highlight to improve performance of selection
theContext->SetAutomaticHilight( Standard_False );
- Handle_SelectMgr_Selection aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) );
+ Handle(SelectMgr_Selection) aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) );
for( aSelection->Init(); aSelection->More(); aSelection->Next() )
- {
- Handle_SelectBasics_SensitiveEntity aSenEntity = aSelection->Sensitive();
- Handle_Select3D_SensitivePoint aSenPnt = Handle_Select3D_SensitivePoint::DownCast( aSenEntity );
+ {
+#if OCC_VERSION_LARGE > 0x06080100
+ const Handle(SelectMgr_SensitiveEntity) aHSenEntity = aSelection->Sensitive();
+ if( aHSenEntity.IsNull() )
+ continue;
+ Handle(SelectBasics_SensitiveEntity) aSenEntity = aHSenEntity->BaseSensitive();
+#else
+ Handle(SelectBasics_SensitiveEntity) aSenEntity = aSelection->Sensitive();
+#endif
+
+ Handle(Select3D_SensitivePoint) aSenPnt = Handle(Select3D_SensitivePoint)::DownCast( aSenEntity );
gp_Pnt anOwnerPnt = aSenPnt->Point();
- Handle_SelectMgr_EntityOwner anOwner = Handle_SelectMgr_EntityOwner::DownCast( aSenPnt->OwnerId() );
+ Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast( aSenPnt->OwnerId() );
CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(),
anExp.Next();
- if (IsBSpline) {
+ if (IsBSpline)
+ {
// There should be a single BSpline curve in the wire.
if (anExp.More()) {
return aResult;
IsClosed = aV[0].IsSame(aV[1]) ? true : false;
- const Standard_Integer aNbPoints = aBSplCurve->NbKnots();
- TColStd_Array1OfReal aKnots(1, aNbPoints);
-
+ Standard_Integer aNbPoints = aBSplCurve->NbKnots();
+ TColStd_Array1OfReal aKnots(1, aNbPoints);
aBSplCurve->Knots(aKnots);
- aResult = new TColgp_HArray1OfPnt(1, aBSplCurve->NbKnots());
- for (i = aKnots.Lower(); i <= aKnots.Upper(); ++i) {
- aResult->SetValue(i, aBSplCurve->Value(aKnots.Value(i)));
- }
- } else {
+ // Don't consider the last point as it coincides with the first
+ if (IsClosed)
+ --aNbPoints;
+
+ aResult = new TColgp_HArray1OfPnt(1, aNbPoints);
+ for (i = 1; i <= aNbPoints; ++i)
+ aResult->SetValue(i, aBSplCurve->Value( aKnots.Value(i) ));
+ }
+ else
+ {
// This is a polyline.
TopTools_ListOfShape aVertices;
Standard_Integer aNbVtx = 1;
IsClosed = aFirstVtx.IsSame(aLastVtx) ? true : false;
+ // Store a last vertex
+ if (!IsClosed)
+ {
+ aVertices.Append(aLastVtx);
+ aNbVtx++;
+ }
+
// Fill the array of points.
aResult = new TColgp_HArray1OfPnt(1, aNbVtx);
// purpose :
//=======================================================================
void CurveCreator_Utils::FindPlane
- (const Handle_TColgp_HArray1OfPnt &thePoints,
+ (const Handle(TColgp_HArray1OfPnt) &thePoints,
gp_Pln &thePlane,
Standard_Integer &thePlnStatus)
{