Part: ModelRefine: adding bspline support
This commit is contained in:
parent
0a94a9b78c
commit
37e0750cd2
|
@ -29,8 +29,11 @@
|
||||||
#include <Geom_Plane.hxx>
|
#include <Geom_Plane.hxx>
|
||||||
#include <Geom_CylindricalSurface.hxx>
|
#include <Geom_CylindricalSurface.hxx>
|
||||||
#include <gp_Ax3.hxx>
|
#include <gp_Ax3.hxx>
|
||||||
|
#include <Geom_BSplineSurface.hxx>
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
#include <gp_Cylinder.hxx>
|
#include <gp_Cylinder.hxx>
|
||||||
|
#include <TColgp_Array2OfPnt.hxx>
|
||||||
|
#include <TColStd_Array1OfReal.hxx>
|
||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
#include <TopoDS_Compound.hxx>
|
#include <TopoDS_Compound.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
|
@ -753,6 +756,162 @@ void collectConicEdges(const TopoDS_Shell &shell, TopTools_IndexedMapOfShape &ma
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FaceTypedBSpline::FaceTypedBSpline() : FaceTypedBase(GeomAbs_BSplineSurface)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FaceTypedBSpline::isEqual(const TopoDS_Face &faceOne, const TopoDS_Face &faceTwo) const
|
||||||
|
{
|
||||||
|
Handle(Geom_BSplineSurface) surfaceOne = Handle(Geom_BSplineSurface)::DownCast(BRep_Tool::Surface(faceOne));
|
||||||
|
Handle(Geom_BSplineSurface) surfaceTwo = Handle(Geom_BSplineSurface)::DownCast(BRep_Tool::Surface(faceTwo));
|
||||||
|
|
||||||
|
if (surfaceOne.IsNull() || surfaceTwo.IsNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (surfaceOne->IsURational() != surfaceTwo->IsURational()) return false;
|
||||||
|
if (surfaceTwo->IsVRational() != surfaceTwo->IsVRational()) return false;
|
||||||
|
if (surfaceOne->IsUPeriodic() != surfaceTwo->IsUPeriodic()) return false;
|
||||||
|
if (surfaceOne->IsVPeriodic() != surfaceTwo->IsVPeriodic()) return false;
|
||||||
|
if (surfaceOne->IsUClosed() != surfaceTwo->IsUClosed()) return false;
|
||||||
|
if (surfaceOne->IsVClosed() != surfaceTwo->IsVClosed()) return false;
|
||||||
|
if (surfaceOne->UDegree() != surfaceTwo->UDegree()) return false;
|
||||||
|
if (surfaceOne->VDegree() != surfaceTwo->VDegree()) return false;
|
||||||
|
|
||||||
|
//pole test
|
||||||
|
int uPoleCountOne(surfaceOne->NbUPoles());
|
||||||
|
int vPoleCountOne(surfaceOne->NbVPoles());
|
||||||
|
int uPoleCountTwo(surfaceTwo->NbUPoles());
|
||||||
|
int vPoleCountTwo(surfaceTwo->NbVPoles());
|
||||||
|
|
||||||
|
if (uPoleCountOne != uPoleCountTwo || vPoleCountOne != vPoleCountTwo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TColgp_Array2OfPnt polesOne(1, uPoleCountOne, 1, vPoleCountOne);
|
||||||
|
TColgp_Array2OfPnt polesTwo(1, uPoleCountTwo, 1, vPoleCountTwo);
|
||||||
|
surfaceOne->Poles(polesOne);
|
||||||
|
surfaceTwo->Poles(polesTwo);
|
||||||
|
|
||||||
|
for (int indexU = 1; indexU <= uPoleCountOne; ++indexU)
|
||||||
|
{
|
||||||
|
for (int indexV = 1; indexV <= vPoleCountOne; ++indexV)
|
||||||
|
{
|
||||||
|
if (!(polesOne.Value(indexU, indexV).IsEqual(polesTwo.Value(indexU, indexV), Precision::Confusion())))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//knot test
|
||||||
|
int uKnotCountOne(surfaceOne->NbUKnots());
|
||||||
|
int vKnotCountOne(surfaceOne->NbVKnots());
|
||||||
|
int uKnotCountTwo(surfaceTwo->NbUKnots());
|
||||||
|
int vKnotCountTwo(surfaceTwo->NbVKnots());
|
||||||
|
if (uKnotCountOne != uKnotCountTwo || vKnotCountOne != vKnotCountTwo)
|
||||||
|
return false;
|
||||||
|
TColStd_Array1OfReal uKnotsOne(1, uKnotCountOne);
|
||||||
|
TColStd_Array1OfReal vKnotsOne(1, vKnotCountOne);
|
||||||
|
TColStd_Array1OfReal uKnotsTwo(1, uKnotCountTwo);
|
||||||
|
TColStd_Array1OfReal vKnotsTwo(1, vKnotCountTwo);
|
||||||
|
surfaceOne->UKnots(uKnotsOne);
|
||||||
|
surfaceOne->VKnots(vKnotsOne);
|
||||||
|
surfaceTwo->UKnots(uKnotsTwo);
|
||||||
|
surfaceTwo->VKnots(vKnotsTwo);
|
||||||
|
for (int indexU = 1; indexU <= uKnotCountOne; ++indexU)
|
||||||
|
if (uKnotsOne.Value(indexU) != uKnotsTwo.Value(indexU))
|
||||||
|
return false;
|
||||||
|
for (int indexV = 1; indexV <= vKnotCountOne; ++indexV)
|
||||||
|
if (vKnotsOne.Value(indexV) != vKnotsTwo.Value(indexV))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//knot sequence.
|
||||||
|
int uKnotSequenceOneCount(uPoleCountOne + surfaceOne->UDegree() + 1);
|
||||||
|
int vKnotSequenceOneCount(vPoleCountOne + surfaceOne->VDegree() + 1);
|
||||||
|
int uKnotSequenceTwoCount(uPoleCountTwo + surfaceTwo->UDegree() + 1);
|
||||||
|
int vKnotSequenceTwoCount(vPoleCountTwo + surfaceTwo->VDegree() + 1);
|
||||||
|
if (uKnotSequenceOneCount != uKnotSequenceTwoCount || vKnotSequenceOneCount != vKnotSequenceTwoCount)
|
||||||
|
return false;
|
||||||
|
TColStd_Array1OfReal uKnotSequenceOne(1, uKnotSequenceOneCount);
|
||||||
|
TColStd_Array1OfReal vKnotSequenceOne(1, vKnotSequenceOneCount);
|
||||||
|
TColStd_Array1OfReal uKnotSequenceTwo(1, uKnotSequenceTwoCount);
|
||||||
|
TColStd_Array1OfReal vKnotSequenceTwo(1, vKnotSequenceTwoCount);
|
||||||
|
surfaceOne->UKnotSequence(uKnotSequenceOne);
|
||||||
|
surfaceOne->VKnotSequence(vKnotSequenceOne);
|
||||||
|
surfaceTwo->UKnotSequence(uKnotSequenceTwo);
|
||||||
|
surfaceTwo->VKnotSequence(vKnotSequenceTwo);
|
||||||
|
for (int indexU = 1; indexU <= uKnotSequenceOneCount; ++indexU)
|
||||||
|
if (uKnotSequenceOne.Value(indexU) != uKnotSequenceTwo.Value(indexU))
|
||||||
|
return false;
|
||||||
|
for (int indexV = 1; indexV <= vKnotSequenceOneCount; ++indexV)
|
||||||
|
if (vKnotSequenceOne.Value(indexV) != vKnotSequenceTwo.Value(indexV))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeomAbs_SurfaceType FaceTypedBSpline::getType() const
|
||||||
|
{
|
||||||
|
return GeomAbs_BSplineSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopoDS_Face FaceTypedBSpline::buildFace(const FaceVectorType &faces) const
|
||||||
|
{
|
||||||
|
std::vector<TopoDS_Wire> wires;
|
||||||
|
|
||||||
|
std::vector<EdgeVectorType> splitEdges;
|
||||||
|
this->boundarySplit(faces, splitEdges);
|
||||||
|
if (splitEdges.empty())
|
||||||
|
return TopoDS_Face();
|
||||||
|
std::vector<EdgeVectorType>::iterator splitIt;
|
||||||
|
for (splitIt = splitEdges.begin(); splitIt != splitEdges.end(); ++splitIt)
|
||||||
|
{
|
||||||
|
BRepLib_MakeWire wireMaker;
|
||||||
|
EdgeVectorType::iterator it;
|
||||||
|
for (it = (*splitIt).begin(); it != (*splitIt).end(); ++it)
|
||||||
|
wireMaker.Add(*it);
|
||||||
|
TopoDS_Wire currentWire = wireMaker.Wire();
|
||||||
|
wires.push_back(currentWire);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(wires.begin(), wires.end(), ModelRefine::WireSort());
|
||||||
|
|
||||||
|
//make face from surface and outer wire.
|
||||||
|
Handle(Geom_BSplineSurface) surface = Handle(Geom_BSplineSurface)::DownCast(BRep_Tool::Surface(faces.at(0)));
|
||||||
|
if (!surface)
|
||||||
|
return TopoDS_Face();
|
||||||
|
std::vector<TopoDS_Wire>::iterator wireIt;
|
||||||
|
wireIt = wires.begin();
|
||||||
|
BRepBuilderAPI_MakeFace faceMaker(surface, *wireIt);
|
||||||
|
if (!faceMaker.IsDone())
|
||||||
|
return TopoDS_Face();
|
||||||
|
|
||||||
|
//add additional boundaries.
|
||||||
|
for (wireIt++; wireIt != wires.end(); ++wireIt)
|
||||||
|
{
|
||||||
|
faceMaker.Add(*wireIt);
|
||||||
|
if (!faceMaker.IsDone())
|
||||||
|
return TopoDS_Face();
|
||||||
|
}
|
||||||
|
|
||||||
|
//fix newly constructed face. Orientation doesn't seem to get fixed the first call.
|
||||||
|
ShapeFix_Face faceFixer(faceMaker.Face());
|
||||||
|
faceFixer.SetContext(new ShapeBuild_ReShape());
|
||||||
|
faceFixer.Perform();
|
||||||
|
if (faceFixer.Status(ShapeExtend_FAIL))
|
||||||
|
return TopoDS_Face();
|
||||||
|
faceFixer.FixOrientation();
|
||||||
|
faceFixer.Perform();
|
||||||
|
if (faceFixer.Status(ShapeExtend_FAIL))
|
||||||
|
return TopoDS_Face();
|
||||||
|
|
||||||
|
return faceFixer.Face();
|
||||||
|
}
|
||||||
|
|
||||||
|
FaceTypedBSpline& ModelRefine::getBSplineObject()
|
||||||
|
{
|
||||||
|
static FaceTypedBSpline object;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
FaceUniter::FaceUniter(const TopoDS_Shell &shellIn) : modifiedSignal(false)
|
FaceUniter::FaceUniter(const TopoDS_Shell &shellIn) : modifiedSignal(false)
|
||||||
{
|
{
|
||||||
workShell = shellIn;
|
workShell = shellIn;
|
||||||
|
@ -766,6 +925,7 @@ bool FaceUniter::process()
|
||||||
deletedShapes.clear();
|
deletedShapes.clear();
|
||||||
typeObjects.push_back(&getPlaneObject());
|
typeObjects.push_back(&getPlaneObject());
|
||||||
typeObjects.push_back(&getCylinderObject());
|
typeObjects.push_back(&getCylinderObject());
|
||||||
|
typeObjects.push_back(&getBSplineObject());
|
||||||
//add more face types.
|
//add more face types.
|
||||||
|
|
||||||
ModelRefine::FaceTypeSplitter splitter;
|
ModelRefine::FaceTypeSplitter splitter;
|
||||||
|
|
|
@ -95,6 +95,18 @@ namespace ModelRefine
|
||||||
};
|
};
|
||||||
FaceTypedCylinder& getCylinderObject();
|
FaceTypedCylinder& getCylinderObject();
|
||||||
|
|
||||||
|
class FaceTypedBSpline : public FaceTypedBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FaceTypedBSpline();
|
||||||
|
public:
|
||||||
|
virtual bool isEqual(const TopoDS_Face &faceOne, const TopoDS_Face &faceTwo) const;
|
||||||
|
virtual GeomAbs_SurfaceType getType() const;
|
||||||
|
virtual TopoDS_Face buildFace(const FaceVectorType &faces) const;
|
||||||
|
friend FaceTypedBSpline& getBSplineObject();
|
||||||
|
};
|
||||||
|
FaceTypedBSpline& getBSplineObject();
|
||||||
|
|
||||||
class FaceTypeSplitter
|
class FaceTypeSplitter
|
||||||
{
|
{
|
||||||
typedef std::map<GeomAbs_SurfaceType, FaceVectorType> SplitMapType;
|
typedef std::map<GeomAbs_SurfaceType, FaceVectorType> SplitMapType;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user