目录
1、添加头文件与源文件
GEOMAlgo_Splitter.h
GEOMAlgo_Splitter.cpp
2、测试
2.1平面分割立方体
2.2以边分面
2.3以面分面
1、添加头文件与源文件
GEOMAlgo_Splitter.h
// Copyright (C) 2007-2019 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
//
// 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, 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
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: GEOMAlgo_Splitter.hxx
//
// Author: Peter KURNEV
#ifndef GEOMAlgo_Splitter_HeaderFile
#define GEOMAlgo_Splitter_HeaderFile
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_BaseAllocator.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BOPAlgo_Builder.hxx>
//=======================================================================
//class : GEOMAlgo_Splitter
//purpose :
//=======================================================================
class GEOMAlgo_Splitter : public BOPAlgo_Builder
{
public:
Standard_EXPORT
GEOMAlgo_Splitter();
Standard_EXPORT
GEOMAlgo_Splitter(const Handle(NCollection_BaseAllocator)& theAllocator);
Standard_EXPORT
virtual ~GEOMAlgo_Splitter();
Standard_EXPORT
void AddTool(const TopoDS_Shape& theShape);
Standard_EXPORT
const TopTools_ListOfShape& Tools()const;
Standard_EXPORT
void SetLimit(const TopAbs_ShapeEnum aLimit);
Standard_EXPORT
TopAbs_ShapeEnum Limit()const;
Standard_EXPORT
void SetLimitMode(const Standard_Integer aMode);
Standard_EXPORT
Standard_Integer LimitMode()const;
Standard_EXPORT
virtual void Clear();
protected:
Standard_EXPORT
virtual void BuildResult(const TopAbs_ShapeEnum theType);
Standard_EXPORT
virtual void PostTreat();
protected:
TopTools_ListOfShape myTools;
TopTools_MapOfShape myMapTools;
TopAbs_ShapeEnum myLimit;
Standard_Integer myLimitMode;
};
#endif
GEOMAlgo_Splitter.cpp
// Copyright (C) 2007-2019 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
//
// 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, 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
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File: GEOMAlgo_Splitter.cxx
// Created: Thu Sep 06 10:54:04 2012
// Author: Peter KURNEV
// <pkv@irinox>
//
#include"GEOMAlgo_Splitter.h"
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRep_Builder.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopExp.hxx>
static
void TreatCompound(const TopoDS_Shape& aC,
TopTools_ListOfShape& aLSX);
//=======================================================================
//function :
//purpose :
//=======================================================================
GEOMAlgo_Splitter::GEOMAlgo_Splitter()
:
BOPAlgo_Builder(),
myTools(myAllocator),
myMapTools(100, myAllocator)
{
myLimit = TopAbs_SHAPE;
myLimitMode = 0;
}
//=======================================================================
//function :
//purpose :
//=======================================================================
GEOMAlgo_Splitter::GEOMAlgo_Splitter
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_Builder(theAllocator),
myTools(myAllocator),
myMapTools(100, myAllocator)
{
myLimit = TopAbs_SHAPE;
myLimitMode = 0;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
GEOMAlgo_Splitter::~GEOMAlgo_Splitter()
{
}
//=======================================================================
//function : AddTool
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::AddTool(const TopoDS_Shape& theShape)
{
if (myMapTools.Add(theShape)) {
myTools.Append(theShape);
//
AddArgument(theShape);
}
}
//=======================================================================
//function : Tools
//purpose :
//=======================================================================
const TopTools_ListOfShape& GEOMAlgo_Splitter::Tools()const
{
return myTools;
}
//=======================================================================
//function : SetLimit
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::SetLimit(const TopAbs_ShapeEnum aLimit)
{
myLimit = aLimit;
}
//=======================================================================
//function : Limit
//purpose :
//=======================================================================
TopAbs_ShapeEnum GEOMAlgo_Splitter::Limit()const
{
return myLimit;
}
//=======================================================================
//function : SetLimitMode
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::SetLimitMode(const Standard_Integer aMode)
{
myLimitMode = aMode;
}
//=======================================================================
//function : LimitMode
//purpose :
//=======================================================================
Standard_Integer GEOMAlgo_Splitter::LimitMode()const
{
return myLimitMode;
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::Clear()
{
myTools.Clear();
myMapTools.Clear();
myLimit = TopAbs_SHAPE;
BOPAlgo_Builder::Clear();
}
//=======================================================================
//function : BuildResult
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
{
TopAbs_ShapeEnum aType;
BRep_Builder aBB;
TopTools_MapOfShape aM;
TopTools_ListIteratorOfListOfShape aIt, aItIm;
//
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
aType = aS.ShapeType();
if (aType == theType && !myMapTools.Contains(aS)) {
if (myImages.IsBound(aS)) {
const TopTools_ListOfShape& aLSIm = myImages.Find(aS);
aItIm.Initialize(aLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSIm = aItIm.Value();
if (aM.Add(aSIm)) {
aBB.Add(myShape, aSIm);
}
}
}
else {
if (aM.Add(aS)) {
aBB.Add(myShape, aS);
}
}
}
}
}
//=======================================================================
//function : PostTreat
//purpose :
//=======================================================================
void GEOMAlgo_Splitter::PostTreat()
{
if (myLimit != TopAbs_SHAPE) {
Standard_Integer i, aNbS;
BRep_Builder aBB;
TopoDS_Compound aC;
TopTools_IndexedMapOfShape aMx;
//
aBB.MakeCompound(aC);
//
TopExp::MapShapes(myShape, myLimit, aMx);
aNbS = aMx.Extent();
for (i = 1; i <= aNbS; ++i) {
const TopoDS_Shape& aS = aMx(i);
aBB.Add(aC, aS);
}
if (myLimitMode) {
Standard_Integer iType, iLimit, iTypeX;
TopAbs_ShapeEnum aType, aTypeX;
TopTools_ListOfShape aLSP, aLSX;
TopTools_ListIteratorOfListOfShape aIt, aItX, aItIm;
TopTools_MapOfShape aM;
//
iLimit = (Standard_Integer)myLimit;
//
// 1. Collect the shapes to process aLSP
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
if (myMapTools.Contains(aS)) {
continue;
}
//
aType = aS.ShapeType();
iType = (Standard_Integer)aType;
//
if (iType > iLimit) {
aLSP.Append(aS);
}
//
else if (aType == TopAbs_COMPOUND) {
aLSX.Clear();
//
TreatCompound(aS, aLSX);
//
aItX.Initialize(aLSX);
for (; aItX.More(); aItX.Next()) {
const TopoDS_Shape& aSX = aItX.Value();
aTypeX = aSX.ShapeType();
iTypeX = (Standard_Integer)aTypeX;
//
if (iTypeX > iLimit) {
aLSP.Append(aSX);
}
}
}
}// for (; aIt.More(); aIt.Next()) {
//
aMx.Clear();
TopExp::MapShapes(aC, aMx);
// 2. Add them to aC
aIt.Initialize(aLSP);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
if (myImages.IsBound(aS)) {
const TopTools_ListOfShape& aLSIm = myImages.Find(aS);
aItIm.Initialize(aLSIm);
for (; aItIm.More(); aItIm.Next()) {
const TopoDS_Shape& aSIm = aItIm.Value();
if (aM.Add(aSIm)) {
if (!aMx.Contains(aSIm)) {
aBB.Add(aC, aSIm);
}
}
}
}
else {
if (aM.Add(aS)) {
if (!aMx.Contains(aS)) {
aBB.Add(aC, aS);
}
}
}
}
}// if (myLimitMode) {
myShape = aC;
}//if (myLimit!=TopAbs_SHAPE) {
//
Standard_Integer aNbS;
TopoDS_Iterator aIt;
TopTools_ListOfShape aLS;
//
aIt.Initialize(myShape);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS = aIt.Value();
aLS.Append(aS);
}
aNbS = aLS.Extent();
if (aNbS == 1) {
myShape = aLS.First();
}
//
//BOPAlgo_Builder::PostTreat();
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void TreatCompound(const TopoDS_Shape& aC1,
TopTools_ListOfShape& aLSX)
{
Standard_Integer aNbC1;
TopAbs_ShapeEnum aType;
TopTools_ListOfShape aLC, aLC1;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
TopoDS_Iterator aItC;
//
aLC.Append(aC1);
for (;;) {
aLC1.Clear();
aIt.Initialize(aLC);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aC = aIt.Value(); //C is compound
//
aItC.Initialize(aC);
for (; aItC.More(); aItC.Next()) {
const TopoDS_Shape& aS = aItC.Value();
aType = aS.ShapeType();
if (aType == TopAbs_COMPOUND) {
aLC1.Append(aS);
}
else {
aLSX.Append(aS);
}
}
}
//
aNbC1 = aLC1.Extent();
if (!aNbC1) {
break;
}
//
aLC.Clear();
aIt.Initialize(aLC1);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSC = aIt.Value();
aLC.Append(aSC);
}
}// while(1)
}
//
// myErrorStatus
//
// 0 - Ok
// 1 - The object is just initialized
// 2 - PaveFiller is failed
// 10 - No shapes to process
// 30 - SolidBuilder failed
2、测试
2.1平面分割立方体
#include <BRepPrimAPI_MakeBox.hxx>
#include"GEOMAlgo_Splitter.h"
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <TopExp_Explorer.hxx>
#include"Viewer.h"
int main(int argc, char* argv[])
{
gp_Pnt p0 = gp_Pnt(5, 5, 5);
gp_Dir vnorm = gp_Dir(1, 1, 1);
gp_Pln pln = gp_Pln(p0, vnorm);
TopoDS_Face face = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10).Face();
TopoDS_Shape box = BRepPrimAPI_MakeBox(10, 10, 10).Shape();
//启动分割函数
GEOMAlgo_Splitter splitter = GEOMAlgo_Splitter();
//将box作为参数,将面face作为分割工具。
splitter.AddArgument(box);
splitter.AddTool(face);
splitter.Perform();
Viewer vout(50, 50, 500, 500);
//显示分割后的体
for (TopExp_Explorer i(splitter.Shape(), TopAbs_SOLID); i.More(); i.Next())
{
vout << i.Current();
}
vout << face;
vout.StartMessageLoop();
return 0;
}
#include <BRepPrimAPI_MakeBox.hxx>
#include"GEOMAlgo_Splitter.h"
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <TopExp_Explorer.hxx>
#include"Viewer.h"
int main(int argc, char* argv[])
{
gp_Pnt p0 = gp_Pnt(5, 5, 5);
gp_Dir vnorm = gp_Dir(1, 1, 1);
gp_Pln pln = gp_Pln(p0, vnorm);
TopoDS_Face face = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10).Face();
TopoDS_Shape box = BRepPrimAPI_MakeBox(10, 10, 10).Shape();
//启动分割函数
GEOMAlgo_Splitter splitter = GEOMAlgo_Splitter();
//将box作为参数,将面face作为分割工具。
splitter.AddArgument(box);
splitter.AddTool(face);
splitter.Perform();
Viewer vout(50, 50, 500, 500);
//显示分割后的体
TopExp_Explorer i(splitter.Shape(), TopAbs_SOLID);
i.Next();
vout << i.Current();
vout << face;
vout.StartMessageLoop();
return 0;
}
2.2以边分面
#include <vector>
#include <gp_Pnt.hxx>
#include <gp_Circ.hxx>
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include"Viewer.h"
#include"GEOMAlgo_Splitter.h"
#include <TopExp_Explorer.hxx>
int main(int argc, char* argv[])
{
gp_Pnt p0 = gp_Pnt();
gp_Dir vnorm = gp_Dir(1, 0, 0);
gp_Pln pln = gp_Pln(p0, vnorm);
TopoDS_Shape face = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10);
gp_Pnt p1 = gp_Pnt(0, 0, 15);
gp_Pnt p2 = gp_Pnt(0, 0, -15);
TopoDS_Shape edge = BRepBuilderAPI_MakeEdge(p1, p2);
//启动分割函数
GEOMAlgo_Splitter splitter = GEOMAlgo_Splitter();
//将面作为参数,将边edge作为分割工具。
splitter.AddArgument(face);
splitter.AddTool(edge);
splitter.Perform();
//显示分割后的体
TopExp_Explorer i(splitter.Shape(), TopAbs_FACE);
i.Next();
Viewer vout(50, 50, 500, 500);
vout << i.Current();
vout << edge;
vout.StartMessageLoop();
return 0;
}
2.3以面分面
#include <vector>
#include <gp_Pnt.hxx>
#include <gp_Circ.hxx>
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include"Viewer.h"
#include"GEOMAlgo_Splitter.h"
#include <TopExp_Explorer.hxx>
int main(int argc, char* argv[])
{
//第一个面
gp_Pnt p0 = gp_Pnt(5, 5, 5);
gp_Dir vnorm = gp_Dir(1, 1, 1);
gp_Pln pln = gp_Pln(p0, vnorm);
TopoDS_Shape face1 = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10);
//工具面
vnorm = gp_Dir(1, 1, 0);
pln = gp_Pln(p0, vnorm);
TopoDS_Shape face2 = BRepBuilderAPI_MakeFace(pln, -20, 20, -20, 20);
//启动分割函数
GEOMAlgo_Splitter splitter = GEOMAlgo_Splitter();
//将面作为参数,将边edge作为分割工具。
splitter.AddArgument(face1);
splitter.AddTool(face2);
splitter.Perform();
//显示分割后的体
TopExp_Explorer i(splitter.Shape(), TopAbs_FACE);
i.Next();
Viewer vout(50, 50, 500, 500);
vout << i.Current();
vout << face2;
vout.StartMessageLoop();
return 0;
}