1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00
occt/samples/mfc/occtdemo/Simplify/Simplify_Presentation.cpp
abv 92efcf78a6 0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
Automatic restore of IMPLEMENT_STANDARD_RTTIEXT macro (upgrade -rtti)
2015-12-04 14:15:06 +03:00

428 lines
13 KiB
C++
Executable File

// Simplify_Presentation.cpp: implementation of the Simplify_Presentation class.
// Simplify shape -> create a new shape based on triangulation of a given shape
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Simplify_Presentation.h"
#include <GeomPlate_Surface.hxx>
#include <GeomPlate_MakeApprox.hxx>
#include <GeomPlate_PointConstraint.hxx>
#include <GeomPlate_BuildPlateSurface.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <BRepMesh.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include <Poly_Triangulation.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <TopLoc_Location.hxx>
#include <ShapeFix_Shape.hxx>
#ifdef WNT
#define EOL "\r\n"
#else
#define EOL "\n"
#endif
// Initialization of global variable with an instance of this class
OCCDemo_Presentation* OCCDemo_Presentation::Current = new Simplify_Presentation;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Simplify_Presentation::Simplify_Presentation()
{
setName ("Simplify shape");
}
//=========================================================================================
// Sample execution
//=========================================================================================
void Simplify_Presentation::DoSample()
{
getAISContext()->EraseAll();
sample("shell1.brep");
}
//////////////////////////////////////////////////////////////////////
// Sample functions
//////////////////////////////////////////////////////////////////////
//================================================================
// Function : Simplify_Presentation::simplify
// Purpose :
//================================================================
void Simplify_Presentation::simplify(const TopoDS_Shape& aShape)
{
setResultTitle("Simplify Face");
setResultText(
" TopoDS_Shape aShape;" EOL
"" EOL
" // initialize aShape" EOL
" //aShape = ..." EOL
"" EOL
" // define parameter triangulation" EOL
" Standard_Real aDeflection = 0.1;" EOL
" " EOL
" // removes all the triangulations of the faces ," EOL
" //and all the polygons on the triangulations of the edges" EOL
" BRepTools::Clean(aShape);" EOL
" // adds a triangulation of the shape aShape with the deflection aDeflection" EOL
" BRepMesh::Mesh(aShape,aDeflection);" EOL
"" EOL
" Standard_Integer aIndex = 1, nbNodes = 0;" EOL
" " EOL
" // define two sequence of points" EOL
" TColgp_SequenceOfPnt aPoints, aPoints1;" EOL
" " EOL
" // triangulation" EOL
" for(TopExp_Explorer aExpFace(aShape,TopAbs_FACE); aExpFace.More(); aExpFace.Next())" EOL
" { " EOL
" TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL
" TopLoc_Location aLocation;" EOL
"" EOL
" // takes the triangulation of the face aFace" EOL
" Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL
"" EOL
" if(!aTr.IsNull())" EOL
" { " EOL
" // takes the array of nodes for this triangulation" EOL
" const TColgp_Array1OfPnt& aNodes = aTr->Nodes(); " EOL
" nbNodes = aNodes.Length();" EOL
"" EOL
" for( Standard_Integer i = 1; i <= nbNodes; i++)" EOL
" {" EOL
" // create seguence of node points in absolute coordinate system" EOL
" gp_Pnt aPnt = aNodes(i).Transformed(aLocation);" EOL
" aPoints.Append(aPnt);" EOL
" " EOL
" }" EOL
" }" EOL
" }" EOL
" " EOL
" // remove double points" EOL
" nbNodes = aPoints.Length();" EOL
" for( Standard_Integer i = 1; i <= nbNodes; i++)" EOL
" {" EOL
" gp_Pnt aPi = aPoints(i);" EOL
" for( Standard_Integer j = i + 1; j < nbNodes; j++)" EOL
" {" EOL
" gp_Pnt aPj = aPoints(j);" EOL
" if(!aPi.IsEqual(aPj,0.9))" EOL
" aIndex++;" EOL
" }" EOL
" if(aIndex == j - 1)" EOL
" aPoints1.Append(aPi);" EOL
"" EOL
" aIndex = i + 1;" EOL
" }" EOL
"" EOL
" // find max point" EOL
" aIndex = 0;" EOL
" gp_Pnt aPntMax = aPoints1(1);" EOL
" nbNodes = aPoints1.Length();" EOL
" for(i = 2; i <= nbNodes; i++)" EOL
" {" EOL
" if(aPoints1(i).X() > aPntMax.X())" EOL
" {" EOL
" aIndex = i;" EOL
" aPntMax = aPoints1(aIndex); " EOL
" } " EOL
" }" EOL
"" EOL
" // clear seguence" EOL
" aPoints.Clear();" EOL
"" EOL
" Standard_Integer nbLeftNodes = nbNodes;" EOL
"" EOL
" // ascending sort - fill aPoints with ascending " EOL
" // by X coordinate points from aPoints1" EOL
" for(i = 1; i < nbNodes; i++)" EOL
" {" EOL
" Standard_Real aMin = aPntMax.X();" EOL
" aIndex = 1;" EOL
" for( Standard_Integer j = 1; j <= nbLeftNodes; j++)" EOL
" {" EOL
" if(aPoints1(j).X() < aMin)" EOL
" {" EOL
" aMin = aPoints1(j).X();" EOL
" aIndex = j;" EOL
" } " EOL
" }" EOL
" aPoints.Append(aPoints1(aIndex));" EOL
" aPoints1.Remove(aIndex);" EOL
" nbLeftNodes = aPoints1.Length();" EOL
" }" EOL
" aPoints.Append(aPntMax);" EOL
"" EOL
" // define parameters GeomPlate_BuildPlateSurface" EOL
" Standard_Integer Degree = 3;" EOL
" Standard_Integer NbPtsOnCur = 10;" EOL
" Standard_Integer NbIter = 3;" EOL
" Standard_Integer Order = 0;" EOL
" Standard_Integer MaxSeg = 9;" EOL
" Standard_Integer MaxDegree = 5;" EOL
" Standard_Real dmax, anApproxTol = 0.001;" EOL
" Standard_Real aConstrTol = Precision::Confusion();" EOL
" " EOL
" // define object BuildPlateSurface" EOL
" GeomPlate_BuildPlateSurface BPSurf(Degree,NbPtsOnCur,NbIter);" EOL
" " EOL
" // add point constraints to GeomPlate_BuildPlateSurface object" EOL
" nbNodes = aPoints.Length();" EOL
" for (i = 1; i <= nbNodes; i++)" EOL
" BPSurf.Add(new GeomPlate_PointConstraint(aPoints(i), Order, aConstrTol));" EOL
"" EOL
" BPSurf.Perform();" EOL
"" EOL
" // make PlateSurface" EOL
" Handle(GeomPlate_Surface) PSurf;" EOL
" Handle(Geom_Surface) aSurf;" EOL
" " EOL
" if (BPSurf.IsDone())" EOL
" {" EOL
" PSurf = BPSurf.Surface();" EOL
"" EOL
" // define parameter approximation" EOL
" dmax = Max(0.01,10*BPSurf.G0Error());" EOL
"" EOL
" // make approximation" EOL
" GeomPlate_MakeApprox Mapp(PSurf,anApproxTol, MaxSeg,MaxDegree,dmax);" EOL
" aSurf = Mapp.Surface();" EOL
" }" EOL
" else " EOL
" return;" EOL
"" EOL
" ShapeAnalysis_FreeBounds aFreeBounds(aShape, Standard_False, Standard_True);" EOL
" TopoDS_Compound aClosedWires = aFreeBounds.GetClosedWires();" EOL
" TopTools_IndexedMapOfShape aWires;" EOL
" TopExp::MapShapes(aClosedWires, TopAbs_WIRE, aWires);" EOL
" TopoDS_Wire aWire;" EOL
" Standard_Integer nbWires = aWires.Extent();" EOL
" if (nbWires) " EOL
" aWire = TopoDS::Wire(aWires(1));" EOL
" else " EOL
" return;" EOL
"" EOL
" BRep_Builder B;" EOL
" TopoDS_Face aFace;" EOL
" B.MakeFace(aFace, aSurf, Precision::Confusion());" EOL
" B.Add(aFace, aWire);" EOL
" Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape(aFace);" EOL
" sfs->Perform();" EOL
" TopoDS_Shape aFixedFace = sfs->Shape();" EOL
" if (aFixedFace.IsNull()) " EOL
" return;" EOL);
// define parameter triangulation
Standard_Real aDeflection = 0.1;
// removes all the triangulations of the faces ,
//and all the polygons on the triangulations of the edges
BRepTools::Clean(aShape);
// adds a triangulation of the shape aShape with the deflection aDeflection
BRepMesh::Mesh(aShape,aDeflection);
Standard_Integer aIndex = 1, nbNodes = 0;
// define two sequence of points
TColgp_SequenceOfPnt aPoints, aPoints1;
// triangulation
for(TopExp_Explorer aExpFace(aShape,TopAbs_FACE); aExpFace.More(); aExpFace.Next())
{
TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
TopLoc_Location aLocation;
// takes the triangulation of the face aFace
Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace,aLocation);
if(!aTr.IsNull())
{
// takes the array of nodes for this triangulation
const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
nbNodes = aNodes.Length();
for( Standard_Integer i = 1; i <= nbNodes; i++)
{
// create seguence of node points in absolute coordinate system
gp_Pnt aPnt = aNodes(i).Transformed(aLocation);
aPoints.Append(aPnt);
}
}
}
// remove double points
nbNodes = aPoints.Length();
for( Standard_Integer i = 1; i <= nbNodes; i++)
{
gp_Pnt aPi = aPoints(i);
for( Standard_Integer j = i + 1; j < nbNodes; j++)
{
gp_Pnt aPj = aPoints(j);
if(!aPi.IsEqual(aPj,0.9))
aIndex++;
}
if(aIndex == j - 1)
aPoints1.Append(aPi);
aIndex = i + 1;
}
// find max point
aIndex = 0;
gp_Pnt aPntMax = aPoints1(1);
nbNodes = aPoints1.Length();
for(i = 2; i <= nbNodes; i++)
{
if(aPoints1(i).X() > aPntMax.X())
{
aIndex = i;
aPntMax = aPoints1(aIndex);
}
}
// clear seguence
aPoints.Clear();
Standard_Integer nbLeftNodes = nbNodes;
// ascending sort - fill aPoints with ascending
// by X coordinate points from aPoints1
for(i = 1; i < nbNodes; i++)
{
Standard_Real aMin = aPntMax.X();
aIndex = 1;
for( Standard_Integer j = 1; j <= nbLeftNodes; j++)
{
if(aPoints1(j).X() < aMin)
{
aMin = aPoints1(j).X();
aIndex = j;
}
}
aPoints.Append(aPoints1(aIndex));
aPoints1.Remove(aIndex);
nbLeftNodes = aPoints1.Length();
}
aPoints.Append(aPntMax);
// define parameters GeomPlate_BuildPlateSurface
Standard_Integer Degree = 3;
Standard_Integer NbPtsOnCur = 10;
Standard_Integer NbIter = 3;
Standard_Integer Order = 0;
Standard_Integer MaxSeg = 9;
Standard_Integer MaxDegree = 5;
Standard_Real dmax, anApproxTol = 0.001;
Standard_Real aConstrTol = Precision::Confusion();
// define object BuildPlateSurface
GeomPlate_BuildPlateSurface BPSurf(Degree,NbPtsOnCur,NbIter);
// add point constraints to GeomPlate_BuildPlateSurface object
nbNodes = aPoints.Length();
for (i = 1; i <= nbNodes; i++)
BPSurf.Add(new GeomPlate_PointConstraint(aPoints(i), Order, aConstrTol));
BPSurf.Perform();
// make PlateSurface
Handle(GeomPlate_Surface) PSurf;
Handle(Geom_Surface) aSurf;
if (BPSurf.IsDone())
{
PSurf = BPSurf.Surface();
// define parameter approximation
dmax = Max(0.01,10*BPSurf.G0Error());
// make approximation
GeomPlate_MakeApprox Mapp(PSurf,anApproxTol, MaxSeg,MaxDegree,dmax);
aSurf = Mapp.Surface();
}
else
return;
ShapeAnalysis_FreeBounds aFreeBounds(aShape, Standard_False, Standard_True);
TopoDS_Compound aClosedWires = aFreeBounds.GetClosedWires();
TopTools_IndexedMapOfShape aWires;
TopExp::MapShapes(aClosedWires, TopAbs_WIRE, aWires);
TopoDS_Wire aWire;
Standard_Integer nbWires = aWires.Extent();
if (nbWires)
aWire = TopoDS::Wire(aWires(1));
else
return;
BRep_Builder B;
TopoDS_Face aFace;
B.MakeFace(aFace, aSurf, Precision::Confusion());
B.Add(aFace, aWire);
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape(aFace);
sfs->Perform();
TopoDS_Shape aFixedFace = sfs->Shape();
if (aFixedFace.IsNull())
return;
// output surface, make it half transparent
Handle(AIS_InteractiveObject) aSurfIO = drawSurface(
aSurf, Quantity_NOC_LEMONCHIFFON3, Standard_False);
aSurfIO->SetTransparency(0.5);
getAISContext()->Display(aSurfIO, Standard_False);
COCCDemoDoc::Fit();
if(WAIT_A_LITTLE) return;
// output points
for(i = 1; i <= nbNodes; i++)
drawPoint(aPoints(i));
if(WAIT_A_LITTLE) return;
// output resulting face
drawShape(aFixedFace);
}
//================================================================
// Function : Simplify_Presentation::sample
// Purpose :
//================================================================
void Simplify_Presentation::sample(const Standard_CString aFileName)
{
TCollection_AsciiString aPath(GetDataDir());
aPath = aPath + "\\" + aFileName;
TopoDS_Shape aShape;
BRep_Builder aBld;
Standard_Boolean isRead = BRepTools::Read (aShape, aPath.ToCString(), aBld);
if (!isRead)
{
aPath += " was not found. The sample can not be shown.";
setResultText(aPath.ToCString());
return;
}
simplify(aShape);
}