To create a curving face using several edges you need to define the
following parameters:
-\n <b>Edges Compound</b> - the list of edges used for creation of the
-surface;
-\n \b Minimum and <b>Maximum Degree</b> of equation of the resulting BSpline or Besier curves describing the surface;
+\n <b>Input Compound</b> - the list of edges/wires used for creation
+of the surface. Before perform filling algorithm each wire from
+compound is converted to one edge created on BSpline curve built using
+curves from all edges from wire.
+\n \b Minimum and <b>Maximum Degree</b> of equation of the resulting
+BSpline or Besier curves describing the surface;
\n \b Tolerance for \b 2D and for \b 3D - minimum distance between the
created surface and the reference edge;
\n <b>Number of
-Iterations</b> - defines the maximum number of iterations. The iterations are repeated until the required tolerance is reached. So, a greater number of iterations allows producing a better surface.
-\n <b>Approximation</b> - if checked, BSpline curves are generated in the process of surface construction (using GeomAPI_PointsToBSplineSurface functionality). By default the surface is created using Besier curves. The usage of <b>Approximation</b> makes the algorithm work slower, but allows building the
-surface for rather complex cases.
+Iterations</b> - defines the maximum number of iterations. The
+iterations are repeated until the required tolerance is reached. So, a
+greater number of iterations allows producing a better surface.
+\n <b>Use orientation</b> - if checked, orientation of edges are used:
+if edge is reversed curve from this edge is reversed before using in
+filling algorithm.
+\n <b>Approximation</b> - if checked, BSpline curves are generated in
+the process of surface construction (using
+GeomAPI_PointsToBSplineSurface functionality). By default the surface
+is created using Besier curves. The usage of <b>Approximation</b>
+makes the algorithm work slower, but allows building the surface for
+rather complex cases.
\n The \b Result of the operation will be a GEOM_Object (face).
\n <b>TUI Command:</b> <em>geompy.MakeFilling(Edges, MinDegree, MaxDegree, Tol2D, Tol3D, NbIter)</em>
-\n <b>Arguments:</b> Name + 1 List of edges + 6 Parameters
+\n <b>Arguments:</b> Name + 1 List of edges + 7 Parameters
(Min. degree, Max. degree, Number of iterations, 2D tolerance, 3D
-tolerance, Number of iterations, Appro).
+tolerance, Number of iterations, Use orientation, Approximation).
\image html filling.png
GEOM_Object MakeFilling (in GEOM_Object theShape,
in long theMinDeg, in long theMaxDeg,
in double theTol2D, in double theTol3D,
- in long theNbIter, in boolean theApprox);
+ in long theNbIter, in boolean theUseOri,
+ in boolean theApprox);
/*!
* Create a shell or solid passing through set of sections.Sections should be wires,edges or vertices.
GEOM_Object MakeFilling (in GEOM_Object theShape,
in long theMinDeg, in long theMaxDeg,
in double theTol2D, in double theTol3D,
- in long theNbIter, in boolean theApprox) ;
+ in long theNbIter, in boolean theUseOri,
+ in boolean theApprox) ;
GEOM_Object MakeThruSections(in ListOfGO theSeqSections,
in boolean theModeSolid,
in double thePreci,
</message>
<message>
<source>GEOM_FILLING_COMPOUND</source>
- <translation>Edges compound</translation>
+ <translation>Input compound</translation>
</message>
<message>
<source>GEOM_FILLING_MAX_DEG</source>
<source>GEOM_FILLING_APPROX</source>
<translation>Approximation</translation>
</message>
+ <message>
+ <source>GEOM_FILLING_USEORI</source>
+ <translation>Use orientation</translation>
+ </message>
<message>
<source>GEOM_WRN_NO_APPROPRIATE_SELECTION</source>
<translation>No appropriate objects selected</translation>
#include <BRep_Tool.hxx>
#include <BRepAlgo.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRep_Builder.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
#include <TopExp_Explorer.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomFill_Line.hxx>
#include <GeomFill_AppSurf.hxx>
#include <ShapeFix_Face.hxx>
#include <GeomAPI_PointsToBSplineSurface.hxx>
#include <Geom_BSplineCurve.hxx>
+#include <GeomAPI_PointsToBSpline.hxx>
+
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+
+//#include <BRepTools.hxx>
+
//=======================================================================
//function : GetID
Standard_Real tol2d = IF.GetTol3D();
Standard_Integer nbiter = IF.GetNbIter();
Standard_Boolean isApprox = IF.GetApprox();
+ Standard_Boolean isUseOri = IF.GetUseOri();
if (mindeg > maxdeg) {
Standard_RangeError::Raise("Minimal degree can not be more than maximal degree");
Standard_Real First, Last;
Handle(Geom_Curve) C;
+ TopoDS_Compound aComp;
+ BRep_Builder B;
+ B.MakeCompound(aComp);
+
TopoDS_Iterator It (aShape);
for (; It.More(); It.Next()) {
Scurrent = It.Value();
- if (Scurrent.ShapeType() != TopAbs_EDGE)
- Standard_ConstructionError::Raise("The argument compound must contain only edges");
+ if (Scurrent.ShapeType() != TopAbs_EDGE) {
+ Handle(Geom_BSplineCurve) newC;
+ if (Scurrent.ShapeType() == TopAbs_WIRE) {
+ TColgp_SequenceOfPnt PntSeq;
+ // collect points
+ for (Ex.Init(Scurrent, TopAbs_EDGE); Ex.More(); Ex.Next()) {
+ TopoDS_Edge E = TopoDS::Edge(Ex.Current());
+ if (BRep_Tool::Degenerated(E)) continue;
+ C = BRep_Tool::Curve(E, First, Last);
+ if( E.Orientation() == TopAbs_REVERSED ) {
+ C->Reverse();
+ }
+ Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C);
+ while( !tc.IsNull() ) {
+ C = tc->BasisCurve();
+ tc = Handle(Geom_TrimmedCurve)::DownCast(C);
+ }
+ int nbp = 10;
+ if( C->IsKind(STANDARD_TYPE(Geom_Line)) ) {
+ nbp = 4;
+ }
+ else if( C->IsKind(STANDARD_TYPE(Geom_Circle)) ||
+ C->IsKind(STANDARD_TYPE(Geom_Ellipse)) ) {
+ nbp = (int)25*fabs(Last-First)/(2*PI);
+ }
+ else if( C->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) {
+ Handle(Geom_BezierCurve) C3d = Handle(Geom_BezierCurve)::DownCast(C);
+ nbp = C3d->NbPoles();
+ }
+ else if( C->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ) {
+ Handle(Geom_BSplineCurve) C3d = Handle(Geom_BSplineCurve)::DownCast(C);
+ nbp = C3d->NbPoles();
+ }
+ else {
+ }
+ if( nbp<4 ) nbp = 4;
+ double dp = (Last-First)/(nbp-1);
+ for(int i=1; i<nbp; i++) {
+ gp_Pnt P;
+ C->D0(First+dp*(i-1),P);
+ PntSeq.Append(P);
+ }
+ }
+ // add last point
+ gp_Pnt P;
+ C->D0(Last,P);
+ PntSeq.Append(P);
+ // create BSpline
+ if(PntSeq.Length()>1) {
+ TColgp_Array1OfPnt Pnts(1,PntSeq.Length());
+ // check orientation of wire
+ if( Scurrent.Orientation() == TopAbs_REVERSED ) {
+ for(int i=1; i<=PntSeq.Length(); i++) {
+ Pnts.SetValue(PntSeq.Length()-i+1,PntSeq.Value(i));
+ }
+ }
+ else {
+ for(int i=1; i<=PntSeq.Length(); i++) {
+ Pnts.SetValue(i,PntSeq.Value(i));
+ }
+ }
+ GeomAPI_PointsToBSpline PTB(Pnts);
+ newC = Handle(Geom_BSplineCurve)::DownCast(PTB.Curve());
+ // set periodic flag if curve is closed
+ //if( newC->IsClosed() ) {
+ // newC->SetPeriodic();
+ //}
+ // create edge
+ double fp = newC->FirstParameter();
+ double lp = newC->FirstParameter();
+ gp_Pnt PF,PL;
+ newC->D0(fp,PF);
+ newC->D0(lp,PL);
+ TopoDS_Vertex VF,VL;
+ B.MakeVertex(VF,PF,1.e-7);
+ B.MakeVertex(VL,PL,1.e-7);
+ TopoDS_Edge newE;
+ B.MakeEdge(newE,newC,1.e-7);
+ B.Add(newE,VF);
+ B.Add(newE,VL.Reversed());
+ Scurrent = newE;
+ }
+ }
+ if(newC.IsNull()) {
+ Standard_ConstructionError::Raise("The argument compound must contain only edges");
+ }
+ }
+ B.Add(aComp,Scurrent);
}
+ aShape = aComp;
if (!isApprox) {
// make filling as in old version of SALOME (before 4.1.1)
if (Scurrent.IsNull() || Scurrent.ShapeType() != TopAbs_EDGE) return 0;
if (BRep_Tool::Degenerated(TopoDS::Edge(Scurrent))) continue;
C = BRep_Tool::Curve(TopoDS::Edge(Scurrent), First, Last);
- if (Scurrent.Orientation() == TopAbs_REVERSED)
- // Mantis isuue 0020659: consider the orientation of the edges
- C = new Geom_TrimmedCurve(C, Last, First);
- else
- C = new Geom_TrimmedCurve(C, First, Last);
+ //if (Scurrent.Orientation() == TopAbs_REVERSED)
+ // // Mantis isuue 0020659: consider the orientation of the edges
+ // C = new Geom_TrimmedCurve(C, Last, First);
+ //else
+ // C = new Geom_TrimmedCurve(C, First, Last);
+ C = new Geom_TrimmedCurve(C, First, Last);
+ if( isUseOri && Scurrent.Orientation() == TopAbs_REVERSED ) {
+ C->Reverse();
+ }
Section.AddCurve(C);
i++;
}
//=============================================================================
Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
(Handle(GEOM_Object) theShape, int theMinDeg, int theMaxDeg,
- double theTol2D, double theTol3D, int theNbIter, bool isApprox)
+ double theTol2D, double theTol3D, int theNbIter,
+ bool isUseOri, bool isApprox)
{
SetErrorCode(KO);
aFI.SetTol3D(theTol3D);
aFI.SetNbIter(theNbIter);
aFI.SetApprox(isApprox);
+ aFI.SetUseOri(isUseOri);
//Compute the Solid value
try {
Standard_EXPORT Handle(GEOM_Object) MakeFilling (Handle(GEOM_Object) theShape,
int theMinDeg, int theMaxDeg,
double theTol2D, double theTol3D,
- int theNbIter, bool isApprox);
+ int theNbIter, bool isUseOri,
+ bool isApprox);
Standard_EXPORT Handle(GEOM_Object) MakeThruSections
(const Handle(TColStd_HSequenceOfTransient)& theSeqSections,
#define FILL_ARG_SHAPE 5
#define FILL_ARG_NBITER 6
#define FILL_ARG_APPROX 7
+#define FILL_ARG_USEORI 8
class GEOMImpl_IFilling
{
void SetApprox(bool theApprox) { _func->SetInteger(FILL_ARG_APPROX, theApprox); }
bool GetApprox() { return _func->GetInteger(FILL_ARG_APPROX); }
+ void SetUseOri(bool theUseOri) { _func->SetInteger(FILL_ARG_USEORI, theUseOri); }
+ bool GetUseOri() { return _func->GetInteger(FILL_ARG_USEORI); }
+
void SetShape(Handle(GEOM_Function) theShape) { _func->SetReference(FILL_ARG_SHAPE, theShape); }
Handle(GEOM_Function) GetShape() { return _func->GetReference(FILL_ARG_SHAPE); }
CORBA::Double theTol2D,
CORBA::Double theTol3D,
CORBA::Long theNbIter,
+ CORBA::Boolean theUseOri,
CORBA::Boolean theApprox)
{
GEOM::GEOM_Object_var aGEOMObject;
//Create the Solid
Handle(GEOM_Object) anObject = GetOperations()->MakeFilling
- (aShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, theApprox);
+ (aShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter,
+ theUseOri, theApprox);
if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn();
GEOM::GEOM_Object_ptr theAxis,
CORBA::Double theAngle);
- GEOM::GEOM_Object_ptr MakeFilling(GEOM::GEOM_Object_ptr theShape, CORBA::Long theMinDeg, CORBA::Long theMaxDeg, CORBA::Double theTol2D, CORBA::Double theTol3D, CORBA::Long theNbIter, CORBA::Boolean theApprox);
+ GEOM::GEOM_Object_ptr MakeFilling(GEOM::GEOM_Object_ptr theShape,
+ CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
+ CORBA::Double theTol2D, CORBA::Double theTol3D,
+ CORBA::Long theNbIter, CORBA::Boolean theUseOri,
+ CORBA::Boolean theApprox);
GEOM::GEOM_Object_ptr MakeThruSections(const GEOM::ListOfGO& theSeqSections,
CORBA::Boolean theModeSolid,
// MakeFilling:
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFilling (GEOM::GEOM_Object_ptr theShape,
- CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
- CORBA::Double theTol2D, CORBA::Double theTol3D,
- CORBA::Long theNbIter, CORBA::Boolean theApprox)
+ CORBA::Long theMinDeg,
+ CORBA::Long theMaxDeg,
+ CORBA::Double theTol2D,
+ CORBA::Double theTol3D,
+ CORBA::Long theNbIter,
+ CORBA::Boolean theUseOri,
+ CORBA::Boolean theApprox)
{
beginService( " GEOM_Superv_i::MakeFilling" );
MESSAGE("GEOM_Superv_i::MakeFilling");
get3DPrimOp();
- GEOM::GEOM_Object_ptr anObj = my3DPrimOp->MakeFilling(theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, theApprox);
+ GEOM::GEOM_Object_ptr anObj =
+ my3DPrimOp->MakeFilling(theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D,
+ theNbIter, theUseOri, theApprox);
endService( " GEOM_Superv_i::MakeFilling" );
return anObj;
}
GEOM::GEOM_Object_ptr MakeFilling (GEOM::GEOM_Object_ptr theShape,
CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
CORBA::Double theTol2D, CORBA::Double theTol3D,
- CORBA::Long theNbIter, CORBA::Boolean theApprox);
+ CORBA::Long theNbIter, CORBA::Boolean theUseOri,
+ CORBA::Boolean theApprox);
GEOM::GEOM_Object_ptr MakeThruSections(const GEOM::ListOfGO& theSeqSections,
CORBA::Boolean theModeSolid,
# @param theTol2D a 2d tolerance to be reached
# @param theTol3D a 3d tolerance to be reached
# @param theNbIter a number of iteration of approximation algorithm
+ # @param isUseOri flag for take into account orientation of edges
# @param isApprox if True, BSpline curves are generated in the process
# of surface construction. By default it is False, that means
# the surface is created using Besier curves. The usage of
# @return New GEOM_Object, containing the created filling surface.
#
# @ref tui_creation_filling "Example"
- def MakeFilling(self, theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, isApprox=0):
+ def MakeFilling(self, theShape, theMinDeg, theMaxDeg, theTol2D,
+ theTol3D, theNbIter, isUseOri=0, isApprox=0):
# Example: see GEOM_TestAll.py
theMinDeg,theMaxDeg,theTol2D,theTol3D,theNbIter,Parameters = ParseParameters(theMinDeg, theMaxDeg,
theTol2D, theTol3D, theNbIter)
anObj = self.PrimOp.MakeFilling(theShape, theMinDeg, theMaxDeg,
- theTol2D, theTol3D, theNbIter, isApprox)
+ theTol2D, theTol3D, theNbIter,
+ isUseOri, isApprox)
RaiseIfFailed("MakeFilling", self.PrimOp)
anObj.SetParameters(Parameters)
return anObj
GroupPoints->TextLabel5->setText( tr( "GEOM_FILLING_MAX_DEG" ) );
GroupPoints->TextLabel6->setText( tr( "GEOM_FILLING_TOL_3D" ) );
GroupPoints->CheckBox1->setText( tr( "GEOM_FILLING_APPROX" ) );
+ GroupPoints->CheckBox2->setText( tr( "GEOM_FILLING_USEORI" ) );
GroupPoints->PushButton1->setIcon( image1 );
GroupPoints->LineEdit1->setReadOnly( true );
myTol3D = 0.0001;
myTol2D = 0.0001;
myNbIter = 0;
+ myIsUseOri = false;
myIsApprox = false;
myOkCompound = false;
connect( GroupPoints->SpinBox4, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
connect( GroupPoints->SpinBox5, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
- connect( GroupPoints->CheckBox1, SIGNAL( stateChanged( int ) ), this, SLOT( ApproxChanged() ) );
+ connect( GroupPoints->CheckBox1, SIGNAL( stateChanged( int ) ),
+ this, SLOT( ApproxChanged() ) );
+
+ connect( GroupPoints->CheckBox2, SIGNAL( stateChanged( int ) ),
+ this, SLOT( UseOriChanged() ) );
connect( myGeomGUI, SIGNAL( SignalDefaultStepValueChanged( double ) ), this, SLOT( SetDoubleSpinBoxStep( double ) ) );
if (GEOMBase::GetShape(aSelectedObject, S) && S.ShapeType() == TopAbs_COMPOUND) {
// myCompound should be a compound of edges
for (TopoDS_Iterator it (S); it.More(); it.Next())
- if (it.Value().ShapeType() != TopAbs_EDGE)
+ if ( it.Value().ShapeType() != TopAbs_EDGE &&
+ it.Value().ShapeType() != TopAbs_WIRE )
return;
myCompound = aSelectedObject;
myOkCompound = true;
displayPreview();
}
+//=================================================================================
+// function : UseOriChanged()
+// purpose :
+//=================================================================================
+void GenerationGUI_FillingDlg::UseOriChanged()
+{
+ myIsUseOri = GroupPoints->CheckBox2->isChecked();
+ displayPreview();
+}
+
//=================================================================================
// function : ApproxChanged()
// purpose :
displayPreview();
}
+
//=================================================================================
// function : createOperation
// purpose :
//=================================================================================
bool GenerationGUI_FillingDlg::execute( ObjectList& objects )
{
- GEOM::GEOM_I3DPrimOperations_var anOper = GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
- GEOM::GEOM_Object_var anObj = anOper->MakeFilling( myCompound, myMinDeg, myMaxDeg,
- myTol2D, myTol3D, myNbIter, myIsApprox );
+ GEOM::GEOM_I3DPrimOperations_var anOper =
+ GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
+ GEOM::GEOM_Object_var anObj =
+ anOper->MakeFilling( myCompound, myMinDeg, myMaxDeg, myTol2D, myTol3D,
+ myNbIter, myIsUseOri, myIsApprox );
if ( !anObj->_is_nil() )
{
if ( !IsPreview() )
Standard_Real myTol2D;
Standard_Integer myNbIter;
bool myIsApprox;
+ bool myIsUseOri;
bool myOkCompound; /* to check when curv. compound is defined */
DlgRef_1Sel5Spin1Check* GroupPoints;
void SelectionIntoArgument();
void SetEditCurrentArgument();
void ValueChangedInSpinBox( double );
+ void UseOriChanged();
void ApproxChanged();
void SetDoubleSpinBoxStep( double );
};