1. Multiple changes in ShapeUpgrade_ShapeDivideArea, ShapeUpgrade_FaceDivide, ShapeUpgrade_FaceDivideArea, ShapeUpgrade_SplitSurface, ShapeUpgrade_SplitSurfaceArea: new methods NbParts and SetSplittingByNumber, changes in ShapeUpgrade_FaceDivideArea::Perform and ShapeUpgrade_SplitSurfaceArea::Compute concerning new modes of splitting.
2. New Draw command "DT_SplitByNumber" for testing new modes of splitting.
3. New subgroups "split_number" and "split_two_numbers" in the group of tests "heal" for testing new modes of splitting.
return 0;
}
+static Standard_Integer splitbynumber (Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char** argv)
+{
+ if (argc < 4) {
+ di << "bad number of arguments\n";
+ return 1;
+ }
+
+ TopoDS_Shape inputShape=DBRep::Get(argv[2], TopAbs_FACE);
+ if (inputShape.IsNull()) {
+ di << "Unknown face\n";
+ return 1;
+ }
+
+ Standard_Integer aNbParts, aNumber1 = 0, aNumber2 = 0;
+ aNbParts = aNumber1 = Draw::Atoi (argv[3]);
+ if (argc > 4)
+ aNumber2 = Draw::Atoi (argv[4]);
+
+ if (argc == 4 && aNbParts <= 0)
+ {
+ di << "Incorrect number of parts\n";
+ return 1;
+ }
+ if (argc == 5 &&
+ (aNumber1 <= 0 || aNumber2 <= 0))
+ {
+ di << "Incorrect numbers in U or V\n";
+ return 1;
+ }
+
+ ShapeUpgrade_ShapeDivideArea tool (inputShape);
+ tool.SetSplittingByNumber (Standard_True);
+ if (argc == 4)
+ tool.NbParts() = aNbParts;
+ else
+ tool.SetNumbersUVSplits (aNumber1, aNumber2);
+ tool.Perform();
+ TopoDS_Shape res = tool.Result();
+
+ ShapeFix::SameParameter ( res, Standard_False );
+ DBRep::Set ( argv[1], res );
+ return 0;
+}
+
static Standard_Integer removeinternalwires (Draw_Interpretor& di,
Standard_Integer argc,
const char** argv)
__FILE__,splitclosed,g);
theCommands.Add ("DT_SplitByArea","result shape maxarea [preci]",
__FILE__,splitarea,g);
+ theCommands.Add ("DT_SplitByNumber","result face number [number2]",
+ __FILE__,splitbynumber,g);
theCommands.Add ("RemoveIntWires","result minarea wholeshape [faces or wires] [moderemoveface ]",
__FILE__,removeinternalwires,g);
//purpose :
//=======================================================================
-Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface()
+Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface(const Standard_Real)
{
Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
if ( SplitSurf.IsNull() ) return Standard_False;
//! Performs splitting of surface and computes the shell
//! from source face.
- Standard_EXPORT virtual Standard_Boolean SplitSurface() Standard_OVERRIDE;
+ Standard_EXPORT virtual Standard_Boolean SplitSurface(const Standard_Real theArea = 0.) Standard_OVERRIDE;
//! Sets the number of cutting lines by which closed face will be split.
//! The resulting faces will be num+1.
//purpose :
//=======================================================================
-Standard_Boolean ShapeUpgrade_FaceDivide::Perform ()
+Standard_Boolean ShapeUpgrade_FaceDivide::Perform (const Standard_Real theArea)
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
if ( myFace.IsNull() ) return Standard_False;
myResult = myFace;
- SplitSurface();
+ SplitSurface (theArea);
SplitCurves();
return Status ( ShapeExtend_DONE );
}
//purpose :
//=======================================================================
-Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface ()
+Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface (const Standard_Real theArea)
{
Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
if ( SplitSurf.IsNull() ) return Standard_False;
if (Vl < aSVl) Vl += Min(dV, aSVl - Vl);
}
- SplitSurf->Init ( surf, Uf, Ul, Vf, Vl );
+ SplitSurf->Init (surf, Uf, Ul, Vf, Vl, theArea);
SplitSurf->Perform(mySegmentMode);
// If surface was neither split nor modified, do nothing
//! The context is used to keep track of former splittings
//! in order to keep sharings. It is updated according to
//! modifications made.
- Standard_EXPORT virtual Standard_Boolean Perform();
+ //! The optional argument <theArea> is used to initialize
+ //! the tool for splitting surface in the case of
+ //! splitting into N parts where N is user-defined.
+ Standard_EXPORT virtual Standard_Boolean Perform(const Standard_Real theArea = 0.);
//! Performs splitting of surface and computes the shell
//! from source face.
- Standard_EXPORT virtual Standard_Boolean SplitSurface();
+ //! The optional argument <theArea> is used to initialize
+ //! the tool for splitting surface in the case of
+ //! splitting into N parts where N is user-defined.
+ Standard_EXPORT virtual Standard_Boolean SplitSurface(const Standard_Real theArea = 0.);
//! Performs splitting of curves of all the edges in the
//! shape and divides these edges.
ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea()
{
myMaxArea = Precision::Infinite();
+ myNbParts = 0;
+ myUnbSplit = myVnbSplit = -1;
+ myIsSplittingByNumber = Standard_False;
SetPrecision(1.e-5);
SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
}
ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea(const TopoDS_Face& F)
{
myMaxArea = Precision::Infinite();
+ myNbParts = 0;
+ myUnbSplit = myVnbSplit = -1;
+ myIsSplittingByNumber = Standard_False;
SetPrecision(1.e-5);
SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
Init(F);
//purpose :
//=======================================================================
- Standard_Boolean ShapeUpgrade_FaceDivideArea::Perform()
+ Standard_Boolean ShapeUpgrade_FaceDivideArea::Perform(const Standard_Real)
{
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
GProp_GProps aGprop;
-
+
BRepGProp::SurfaceProperties(myFace,aGprop,Precision());
Standard_Real anArea = aGprop.Mass();
+
+ Standard_Integer anbParts = 0;
+ if (myMaxArea == -1)
+ {
+ anbParts = myNbParts;
+ myMaxArea = anArea / anbParts;
+ }
+
if((anArea - myMaxArea) < Precision::Confusion())
return Standard_False;
-
- Standard_Integer anbParts = RealToInt(ceil(anArea/myMaxArea));
+
+ if (anbParts == 0)
+ anbParts = RealToInt(ceil(anArea/myMaxArea));
+
Handle(ShapeUpgrade_SplitSurfaceArea) aSurfTool= Handle(ShapeUpgrade_SplitSurfaceArea)::
DownCast(GetSplitSurfaceTool ());
if(aSurfTool.IsNull())
return Standard_False;
aSurfTool->NbParts() = anbParts;
- if(!ShapeUpgrade_FaceDivide::Perform())
+ if (myIsSplittingByNumber)
+ {
+ aSurfTool->SetSplittingIntoSquares(Standard_True);
+ aSurfTool->SetNumbersUVSplits (myUnbSplit, myVnbSplit);
+ }
+ if (!ShapeUpgrade_FaceDivide::Perform (anArea))
return Standard_False;
TopoDS_Shape aResult = Result();
if(aResult.ShapeType() == TopAbs_FACE)
return Standard_False;
Standard_Integer aStatus = myStatus;
- TopExp_Explorer aExpF(aResult,TopAbs_FACE);
- TopoDS_Shape aCopyRes = aResult.EmptyCopied();
-
- Standard_Boolean isModified = Standard_False;
- for( ; aExpF.More() ; aExpF.Next()) {
- TopoDS_Shape aSh = Context()->Apply(aExpF.Current());
- TopoDS_Face aFace = TopoDS::Face(aSh);
- Init(aFace);
- BRep_Builder aB;
- if(Perform()) {
- isModified = Standard_True;
- TopoDS_Shape aRes = Result();
- TopExp_Explorer aExpR(aRes,TopAbs_FACE);
- for( ; aExpR.More(); aExpR.Next())
- aB.Add(aCopyRes,aExpR.Current());
- }
- else
- aB.Add(aCopyRes,aFace);
- }
- if(isModified)
+
+ if (!myIsSplittingByNumber)
{
- if (aCopyRes.ShapeType() == TopAbs_WIRE || aCopyRes.ShapeType() == TopAbs_SHELL)
- aCopyRes.Closed (BRep_Tool::IsClosed (aCopyRes));
- Context()->Replace(aResult,aCopyRes);
+ TopExp_Explorer aExpF(aResult,TopAbs_FACE);
+ TopoDS_Shape aCopyRes = aResult.EmptyCopied();
+
+ Standard_Boolean isModified = Standard_False;
+ for( ; aExpF.More() ; aExpF.Next()) {
+ TopoDS_Shape aSh = Context()->Apply(aExpF.Current());
+ TopoDS_Face aFace = TopoDS::Face(aSh);
+ Init(aFace);
+ BRep_Builder aB;
+ if(Perform()) {
+ isModified = Standard_True;
+ TopoDS_Shape aRes = Result();
+ TopExp_Explorer aExpR(aRes,TopAbs_FACE);
+ for( ; aExpR.More(); aExpR.Next())
+ aB.Add(aCopyRes,aExpR.Current());
+ }
+ else
+ aB.Add(aCopyRes,aFace);
+ }
+ if(isModified)
+ {
+ if (aCopyRes.ShapeType() == TopAbs_WIRE || aCopyRes.ShapeType() == TopAbs_SHELL)
+ aCopyRes.Closed (BRep_Tool::IsClosed (aCopyRes));
+ Context()->Replace(aResult,aCopyRes);
+ }
}
+
myStatus |= aStatus;
myResult = Context()->Apply ( aResult );
return Status ( ShapeExtend_DONE );
//! Performs splitting and computes the resulting shell
//! The context is used to keep track of former splittings
- Standard_EXPORT virtual Standard_Boolean Perform() Standard_OVERRIDE;
+ Standard_EXPORT virtual Standard_Boolean Perform(const Standard_Real theArea = 0.) Standard_OVERRIDE;
//! Set max area allowed for faces
Standard_Real& MaxArea();
+ //! Set number of parts expected
+ Standard_Integer& NbParts();
+ //! Set fixed numbers of splits in U and V directions.
+ //! Only for "Splitting By Numbers" mode
+ void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits);
+
+ //! Set splitting mode
+ //! If the mode is "splitting by number",
+ //! the face is splitted approximately into <myNbParts> parts,
+ //! the parts are similar to squares in 2D.
+ void SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber);
DEFINE_STANDARD_RTTIEXT(ShapeUpgrade_FaceDivideArea,ShapeUpgrade_FaceDivide)
Standard_Real myMaxArea;
-
+ Standard_Integer myNbParts;
+ Standard_Integer myUnbSplit;
+ Standard_Integer myVnbSplit;
+ Standard_Boolean myIsSplittingByNumber;
};
}
+inline Standard_Integer& ShapeUpgrade_FaceDivideArea::NbParts()
+{
+ return myNbParts;
+}
+
+inline void ShapeUpgrade_FaceDivideArea::SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber)
+{
+ myIsSplittingByNumber = theIsSplittingByNumber;
+}
+
+inline void ShapeUpgrade_FaceDivideArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits)
+{
+ myUnbSplit = theNbUsplits;
+ myVnbSplit = theNbVsplits;
+ if (myUnbSplit > 0 && myVnbSplit > 0)
+ myNbParts = myUnbSplit * myVnbSplit;
+}
ShapeUpgrade_ShapeDivide()
{
myMaxArea = Precision::Infinite();
+ myNbParts = 0;
+ myUnbSplit = myVnbSplit = -1;
+ myIsSplittingByNumber = Standard_False;
}
//=======================================================================
{
myMaxArea = Precision::Infinite();
+ myNbParts = 0;
+ myUnbSplit = myVnbSplit = -1;
+ myIsSplittingByNumber = Standard_False;
}
//=======================================================================
{
Handle(ShapeUpgrade_FaceDivideArea) aFaceTool = new ShapeUpgrade_FaceDivideArea;
aFaceTool->MaxArea() = myMaxArea;
+ aFaceTool->NbParts() = myNbParts;
+ aFaceTool->SetNumbersUVSplits (myUnbSplit, myVnbSplit);
+ aFaceTool->SetSplittingByNumber (myIsSplittingByNumber);
return aFaceTool;
}
//! Set max area allowed for faces
Standard_Real& MaxArea();
-
+ //! Set number of parts expected
+ //! for the case of splitting by number
+ Standard_Integer& NbParts();
+
+ //! Set fixed numbers of splits in U and V directions.
+ //! Only for "Splitting By Numbers" mode
+ void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits);
+
+ //! Set splitting mode
+ //! If the mode is "splitting by number",
+ //! the face is splitted approximately into <myNbParts> parts,
+ //! the parts are similar to squares in 2D.
+ void SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber);
protected:
- Standard_Real myMaxArea;
-
+ Standard_Real myMaxArea;
+ Standard_Integer myNbParts;
+ Standard_Integer myUnbSplit;
+ Standard_Integer myVnbSplit;
+ Standard_Boolean myIsSplittingByNumber;
};
return myMaxArea;
}
+inline Standard_Integer& ShapeUpgrade_ShapeDivideArea::NbParts()
+{
+ return myNbParts;
+}
+
+inline void ShapeUpgrade_ShapeDivideArea::SetSplittingByNumber(const Standard_Boolean theIsSplittingByNumber)
+{
+ myIsSplittingByNumber = theIsSplittingByNumber;
+ if (myIsSplittingByNumber)
+ myMaxArea = -1;
+}
+inline void ShapeUpgrade_ShapeDivideArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits)
+{
+ myIsSplittingByNumber = Standard_True;
+ myMaxArea = -1;
+ myUnbSplit = theNbUsplits;
+ myVnbSplit = theNbVsplits;
+ if (myUnbSplit > 0 && myVnbSplit > 0)
+ myNbParts = myUnbSplit * myVnbSplit;
+}
#include <TColGeom_HArray2OfSurface.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_HSequenceOfReal.hxx>
+#include <TopoDS_Edge.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_SplitSurface,Standard_Transient)
//purpose :
//=======================================================================
-void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S, const Standard_Real UFirst,const Standard_Real ULast,
- const Standard_Real VFirst, const Standard_Real VLast)
+void ShapeUpgrade_SplitSurface::Init(const Handle(Geom_Surface)& S,
+ const Standard_Real UFirst, const Standard_Real ULast,
+ const Standard_Real VFirst, const Standard_Real VLast,
+ const Standard_Real theArea)
{
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
myNbResultingRow =1;
myNbResultingCol =1;
+ myArea = theArea;
+
Standard_Real U1,U2,V1,V2;
mySurface->Bounds(U1,U2,V1,V2);
Standard_Real precision = Precision::PConfusion();
VF = Max(V1,VFirst);
VL = Min(V2,VLast);
}
+
+ if (myArea != 0.)
+ {
+ //<myArea> is set and will be used with <myUsize> and <myVsize>
+ //in further computations
+ Standard_Real Umid = (UF + UL)/2, Vmid = (VF + VL)/2;
+ Handle (Geom_RectangularTrimmedSurface) aTrSurf =
+ new Geom_RectangularTrimmedSurface (mySurface, UF, UL, VF, VL);
+ Handle(Geom_Curve) anUiso = aTrSurf->UIso (Umid);
+ Handle(Geom_Curve) aViso = aTrSurf->VIso (Vmid);
+ TopoDS_Edge anEdgeUiso = BRepLib_MakeEdge (anUiso);
+ TopoDS_Edge anEdgeViso = BRepLib_MakeEdge (aViso);
+ GProp_GProps aGprop1, aGprop2;
+ BRepGProp::LinearProperties (anEdgeViso, aGprop1);
+ myUsize = aGprop1.Mass();
+ BRepGProp::LinearProperties (anEdgeUiso, aGprop2);
+ myVsize = aGprop2.Mass();
+ }
if(UL-UF < precision) {
Standard_Real p2 = precision/2.;
Standard_EXPORT void Init (const Handle(Geom_Surface)& S);
//! Initializes with single supporting surface with bounding parameters.
- Standard_EXPORT void Init (const Handle(Geom_Surface)& S, const Standard_Real UFirst, const Standard_Real ULast, const Standard_Real VFirst, const Standard_Real VLast);
+ Standard_EXPORT void Init (const Handle(Geom_Surface)& S,
+ const Standard_Real UFirst, const Standard_Real ULast,
+ const Standard_Real VFirst, const Standard_Real VLast,
+ const Standard_Real theArea = 0.);
//! Sets U parameters where splitting has to be done
Standard_EXPORT void SetUSplitValues (const Handle(TColStd_HSequenceOfReal)& UValues);
Handle(Geom_Surface) mySurface;
Standard_Integer myStatus;
Handle(ShapeExtend_CompositeSurface) myResSurfaces;
+ Standard_Real myArea;
+ Standard_Real myUsize;
+ Standard_Real myVsize;
private:
ShapeUpgrade_SplitSurfaceArea::ShapeUpgrade_SplitSurfaceArea():
ShapeUpgrade_SplitSurface()
{
- myNbParts =1;
+ myNbParts = 1;
+ myUnbSplit = myVnbSplit = -1;
+ myIsSplittingIntoSquares = Standard_False;
}
//=======================================================================
Standard_Real aNbUV = aUSize/aVSize;
Handle(TColStd_HSequenceOfReal) aFirstSplit = (aNbUV <1. ? myVSplitValues : myUSplitValues);
Handle(TColStd_HSequenceOfReal) aSecondSplit = (aNbUV <1. ? myUSplitValues : myVSplitValues);
+ Standard_Boolean anIsUFirst = (aNbUV > 1.);
if(aNbUV<1)
aNbUV = 1./aNbUV;
-
- Standard_Integer nbSplitF = (aNbUV >= myNbParts ? myNbParts : RealToInt(ceil(sqrt(myNbParts*ceil(aNbUV)))));
- Standard_Integer nbSplitS = (aNbUV >= myNbParts ? 0 : RealToInt(ceil((Standard_Real)myNbParts/(Standard_Real)nbSplitF)));
- if(nbSplitS ==1)
+
+ Standard_Boolean anIsFixedUVnbSplits = (myUnbSplit > 0 && myVnbSplit > 0);
+ Standard_Integer nbSplitF, nbSplitS;
+ if (myIsSplittingIntoSquares && myNbParts > 0)
+ {
+ if (!anIsFixedUVnbSplits) //(myUnbSplit <= 0 || myVnbSplit <= 0)
+ {
+ Standard_Real aSquareSize = Sqrt (myArea / myNbParts);
+ myUnbSplit = (Standard_Integer)(myUsize / aSquareSize);
+ myVnbSplit = (Standard_Integer)(myVsize / aSquareSize);
+ if (myUnbSplit == 0)
+ myUnbSplit = 1;
+ if (myVnbSplit == 0)
+ myVnbSplit = 1;
+ }
+
+ if (anIsUFirst)
+ {
+ nbSplitF = myUnbSplit;
+ nbSplitS = myVnbSplit;
+ }
+ else
+ {
+ nbSplitF = myVnbSplit;
+ nbSplitS = myUnbSplit;
+ }
+ }
+ else
+ {
+ nbSplitF = (aNbUV >= myNbParts ? myNbParts : RealToInt(ceil(sqrt(myNbParts*ceil(aNbUV)))));
+ nbSplitS = (aNbUV >= myNbParts ? 0 : RealToInt(ceil((Standard_Real)myNbParts/(Standard_Real)nbSplitF)));
+ }
+ if(nbSplitS ==1 && !anIsFixedUVnbSplits)
nbSplitS++;
if(!nbSplitF)
return;
//! Set number of split for surfaces
Standard_Integer& NbParts();
+ //! Set splitting mode
+ //! If the mode is "splitting into squares",
+ //! the face is splitted approximately into <myNbParts> parts,
+ //! the parts are similar to squares in 2D.
+ void SetSplittingIntoSquares(const Standard_Boolean theIsSplittingIntoSquares);
+
+ //! Set fixed numbers of splits in U and V directions.
+ //! Only for "Splitting Into Squares" mode
+ void SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits);
+
Standard_EXPORT virtual void Compute (const Standard_Boolean Segment = Standard_True) Standard_OVERRIDE;
Standard_Integer myNbParts;
+ Standard_Integer myUnbSplit;
+ Standard_Integer myVnbSplit;
+ Standard_Boolean myIsSplittingIntoSquares;
};
return myNbParts;
}
+inline void ShapeUpgrade_SplitSurfaceArea::SetSplittingIntoSquares(const Standard_Boolean theIsSplittingIntoSquares)
+{
+ myIsSplittingIntoSquares = theIsSplittingIntoSquares;
+}
+inline void ShapeUpgrade_SplitSurfaceArea::SetNumbersUVSplits(const Standard_Integer theNbUsplits,
+ const Standard_Integer theNbVsplits)
+{
+ myUnbSplit = theNbUsplits;
+ myVnbSplit = theNbVsplits;
+ if (myUnbSplit > 0 && myVnbSplit > 0)
+ myNbParts = myUnbSplit * myVnbSplit;
+}
023 unify_same_domain
024 same_parameter_locked
025 update_tolerance_locked
-026 checkshape
\ No newline at end of file
+026 checkshape
+027 split_number
+028 split_two_numbers
\ No newline at end of file
--- /dev/null
+psphere a 10 0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 10
+
--- /dev/null
+psphere a 10 0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 102
+
--- /dev/null
+psphere a 10 0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 10
+
--- /dev/null
+psphere a 10 0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 101
+
--- /dev/null
+psphere a 10 0 90 90
+trotate a 0 0 0 0 0 1 -90
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 8
+
--- /dev/null
+psphere a 10 0 90 90
+trotate a 0 0 0 0 0 1 -90
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 96
+
--- /dev/null
+psphere a 10
+fit
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 10
+
--- /dev/null
+psphere a 10
+fit
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 136
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 10
+
+checknbshapes result -t -face 9
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 100
+
+checknbshapes result -t -face 106
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 15
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 125
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 5 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 10
+
+checknbshapes result -t -face 9
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 5 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 100
+
+checknbshapes result -t -face 106
+
--- /dev/null
+polyline a 0 0 0 10 0 0 2 5 0 0 0 0
+mkplane a a
+
+DT_SplitByNumber result a 10
+
+checknbshapes result -t -face 14
+
--- /dev/null
+polyline a 0 0 0 10 0 0 2 5 0 0 0 0
+mkplane a a
+
+DT_SplitByNumber result a 100
+
+checknbshapes result -t -face 118
+
--- /dev/null
+pcylinder a 10 50
+plane pp -20 0 10 1 0 0
+pcylinder b1 pp 3 40
+plane pp 0 -20 30 0 1 0
+pcylinder b2 pp 5 40
+bcut a a b1
+bcut a a b2
+explode a f
+
+DT_SplitByNumber result a_1 10
+
+checknbshapes result -t -face 6
+
--- /dev/null
+pcylinder a 10 50
+plane pp -20 0 10 1 0 0
+pcylinder b1 pp 3 40
+plane pp 0 -20 30 0 1 0
+pcylinder b2 pp 5 40
+bcut a a b1
+bcut a a b2
+explode a f
+
+DT_SplitByNumber result a_1 100
+
+checknbshapes result -t -face 99
+
--- /dev/null
+puts [checkshape result]
--- /dev/null
+psphere a 10 0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 3 5
+
+checknbshapes result -t -face 15
+
--- /dev/null
+psphere a 10 0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 1 5
+
+checknbshapes result -t -face 5
+
--- /dev/null
+psphere a 10 0 90
+fit
+explode a f
+
+DT_SplitByNumber result a_1 5 1
+
+checknbshapes result -t -face 5
+
--- /dev/null
+psphere a 10 0 90
+pcylinder cc 4 15
+ttranslate cc 0 -5 0
+bcut b a cc
+explode b f
+
+DT_SplitByNumber result b_1 3 5
+
+checknbshapes result -t -face 16
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 3 5
+
+checknbshapes result -t -face 15
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 1 5
+
+checknbshapes result -t -face 5
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+
+DT_SplitByNumber result a_4 5 1
+
+checknbshapes result -t -face 5
+
--- /dev/null
+restore [locate_data_file HOMAG_004.brep] a
+explode a f
+pcylinder cc 60 30
+explode cc f
+ttranslate cc_1 100 100 0
+bcut b a_4 cc_1
+explode b
+
+DT_SplitByNumber result b_1 3 5
+
+checknbshapes result -t -face 14
+
--- /dev/null
+puts [checkshape result]