1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50:49 +03:00
Files
occt/src/TopoDSToStep/TopoDSToStep_WireframeBuilder.cxx

419 lines
14 KiB
C++

// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//:S4134 abv 10.03.99: working methods moved from package TopoDSToGBWire
//:j1 modified by abv 22 Oct 98: CSR BUC60401
// - unused parts of code dropped
// - fixed trimming of circles and ellipses (radians used instead of degrees)
//szv#4 S4163
#include <Adaptor3d_CurveOnSurface.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepTools.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomToStep_MakeCartesianPoint.hxx>
#include <GeomToStep_MakeCurve.hxx>
#include <GeomToStep_MakeLine.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_NullObject.hxx>
#include <StdFail_NotDone.hxx>
#include <StepGeom_CartesianPoint.hxx>
#include <StepGeom_Line.hxx>
#include <StepGeom_TrimmedCurve.hxx>
#include <StepGeom_TrimmingSelect.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDSToStep_Tool.hxx>
#include <TopoDSToStep_WireframeBuilder.hxx>
#include <Transfer_FinderProcess.hxx>
// ============================================================================
// Method : TopoDSToStep_Builder::TopoDSToStep_Builder
// Purpose :
// ============================================================================
TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder()
: myError(TopoDSToStep_BuilderOther)
{
done = Standard_False;
}
// ============================================================================
// Method : TopoDSToStep_Builder::TopoDSToStep_Builder
// Purpose :
// ============================================================================
TopoDSToStep_WireframeBuilder::TopoDSToStep_WireframeBuilder(const TopoDS_Shape& aShape, TopoDSToStep_Tool& aTool, const Handle(Transfer_FinderProcess)& FP)
{
done = Standard_False;
Init(aShape, aTool, FP);
}
void TopoDSToStep_WireframeBuilder::Init(const TopoDS_Shape& aShape, TopoDSToStep_Tool& /* T */, const Handle(Transfer_FinderProcess)& /* FP */)
{
Handle(TColStd_HSequenceOfTransient) itemList =
new TColStd_HSequenceOfTransient();
MoniTool_DataMapOfShapeTransient aPmsMap;
done = GetTrimmedCurveFromShape(aShape, aPmsMap, itemList);
myResult = itemList;
}
// ============================================================================
// Method : TopoDSToStep_Builder::Error
// Purpose :
// ============================================================================
TopoDSToStep_BuilderError TopoDSToStep_WireframeBuilder::Error() const
{
return myError;
}
// ============================================================================
// Method : TopoDSToStep_Builder::Value
// Purpose :
// ============================================================================
const Handle(TColStd_HSequenceOfTransient)& TopoDSToStep_WireframeBuilder::Value() const
{
StdFail_NotDone_Raise_if (!done, "TopoDSToStep_WireframeBuilder::Value() - no result");
return myResult;
}
// ============================================================================
//:S4134: abv 10 Mar 99: the methods below moved from package TopoDSToGBWire
#define Nbpt 23
static Handle(StepGeom_TrimmedCurve) MakeTrimmedCurve (const Handle(StepGeom_Curve) &C,
const Handle(StepGeom_CartesianPoint) P1,
const Handle(StepGeom_CartesianPoint) P2,
Standard_Real trim1,
Standard_Real trim2,
Standard_Boolean sense)
{
Handle(StepGeom_HArray1OfTrimmingSelect) aSTS1 =
new StepGeom_HArray1OfTrimmingSelect(1,2);
StepGeom_TrimmingSelect tSel;
tSel.SetValue(P1);
aSTS1->SetValue(1,tSel);
tSel.SetParameterValue(trim1);
aSTS1->SetValue(2,tSel);
Handle(StepGeom_HArray1OfTrimmingSelect) aSTS2 =
new StepGeom_HArray1OfTrimmingSelect(1,2);
tSel.SetValue(P2);
aSTS2->SetValue(1,tSel);
tSel.SetParameterValue(trim2);
aSTS2->SetValue(2,tSel);
Handle(TCollection_HAsciiString) empty =
new TCollection_HAsciiString("");
Handle(StepGeom_TrimmedCurve) pmsTC = new StepGeom_TrimmedCurve;
pmsTC->Init(empty,C,aSTS1,aSTS2,sense,StepGeom_tpParameter);
return pmsTC;
}
Standard_Boolean TopoDSToStep_WireframeBuilder::
GetTrimmedCurveFromEdge(const TopoDS_Edge& theEdge,
const TopoDS_Face& theFace,
MoniTool_DataMapOfShapeTransient& theMap,
Handle(TColStd_HSequenceOfTransient)& theCurveList) const
{
if (theEdge.Orientation() == TopAbs_INTERNAL ||
theEdge.Orientation() == TopAbs_EXTERNAL )
{
#ifdef OCCT_DEBUG
std::cout <<"Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Edge is internal or external; dropped" << std::endl;
#endif
return Standard_False;
}
//szv#4:S4163:12Mar99 SGI warns
TopoDS_Shape aSh = theEdge.Oriented(TopAbs_FORWARD);
TopoDS_Edge anEdge = TopoDS::Edge ( aSh );
// resulting curve
Handle(StepGeom_Curve) aSGC;
if (const Handle(Standard_Transient)* aTransient = theMap.Seek(anEdge))
{
aSGC = Handle(StepGeom_Curve)::DownCast(*aTransient);
}
BRepAdaptor_Curve aCA;
try
{
OCC_CATCH_SIGNALS
aCA.Initialize (anEdge);
}
catch (Standard_NullObject const&)
{
return Standard_False;
}
TopoDS_Vertex aVFirst, aVLast;
Handle(StepGeom_CartesianPoint) aSGCP1, aSGCP2;
for (TopExp_Explorer anExp(anEdge, TopAbs_VERTEX); anExp.More(); anExp.Next())
{
TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Value());
gp_Pnt aGpP = BRep_Tool::Pnt(aVertex);
if (aVertex.Orientation() == TopAbs_FORWARD)
{
aVFirst = aVertex;
// 1.point for trimming
GeomToStep_MakeCartesianPoint aGTSMCP(aGpP);
aSGCP1 = aGTSMCP.Value();
}
if (aVertex.Orientation() == TopAbs_REVERSED)
{
aVLast = aVertex;
// 2.point for trimming
GeomToStep_MakeCartesianPoint aGTSMCP(aGpP);
aSGCP2 = aGTSMCP.Value();
}
}
Standard_Real aFirst, aLast;
Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFirst, aLast);
if (!aC.IsNull())
{
if (aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
{
aC = Handle(Geom_TrimmedCurve)::DownCast(aC)->BasisCurve();
}
GeomToStep_MakeCurve aGTSMC(aC);
if (!aGTSMC.IsDone())
{
return Standard_False;
}
Handle(StepGeom_Curve) aPMSC = aGTSMC.Value();
// trim the curve
Standard_Real aTrim1 = aCA.FirstParameter();
Standard_Real aTrim2 = aCA.LastParameter();
if (aVFirst.IsNull() && aVLast.IsNull() && Precision::IsInfinite(aFirst) && Precision::IsInfinite(aLast))
{
GeomToStep_MakeCurve aCurveMaker(aC);
if (aCurveMaker.IsDone())
{
aSGC = aCurveMaker.Value();
theCurveList->Append(aSGC);
return Standard_True;
}
return Standard_False;
}
if (aVFirst.IsNull())
{
GeomToStep_MakeCartesianPoint aGTSMCP(aCA.Value(aFirst));
aSGCP1 = aGTSMCP.Value();
}
if (aVLast.IsNull())
{
GeomToStep_MakeCartesianPoint aGTSMCP(aCA.Value(aLast));
aSGCP2 = aGTSMCP.Value();
}
/* //:j1 abv 22 Oct 98: radians are used in the produced STEP file (at least by default)
if(C->IsKind(STANDARD_TYPE(Geom_Circle)) ||
C->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
Standard_Real fact = 180. / M_PI;
trim1 = trim1 * fact;
trim2 = trim2 * fact;
}
*/
aSGC = MakeTrimmedCurve(aPMSC, aSGCP1, aSGCP2, aTrim1, aTrim2, Standard_True);
}
else
{
// -------------------------
// a 3D Curve is constructed
// -------------------------
Standard_Boolean aIPlan = Standard_False;
if (!theFace.IsNull())
{
Standard_Real aCF, aCL;
Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, theFace, aCF, aCL);
Handle(Geom_Surface) aS = BRep_Tool::Surface(theFace);
if (aS->IsKind(STANDARD_TYPE(Geom_Plane)) && aC2d->IsKind(STANDARD_TYPE(Geom2d_Line)))
{
aIPlan = Standard_True;
}
}
// to be modified : cf and cl are the topological trimming parameter
// these are computed after ! (U1 and U2) -> cf and cl instead
if (aIPlan)
{
gp_Pnt aPnt1 = aCA.Value(aCA.FirstParameter()), aPnt2 = aCA.Value(aCA.LastParameter());
gp_Vec aV(aPnt1, aPnt2);
Standard_Real aLength = aV.Magnitude();
if (aLength >= Precision::Confusion())
{
Handle(Geom_Line) aL = new Geom_Line(aPnt1, gp_Dir(aV));
GeomToStep_MakeLine aGTSML(aL);
aSGC = aGTSML.Value();
aSGC = MakeTrimmedCurve(aGTSML.Value(), aSGCP1, aSGCP2, 0, aLength, Standard_True);
}
#ifdef OCCT_DEBUG
else std::cout << "Warning: TopoDSToStep_WireframeBuilder::GetTrimmedCurveFromEdge: Null-length curve not mapped" << std::endl;
#endif
}
else
{
TColgp_Array1OfPnt aPoints(1, Nbpt);
TColStd_Array1OfReal aKnots(1, Nbpt);
TColStd_Array1OfInteger aMult(1, Nbpt);
Standard_Real aU1 = aCA.FirstParameter();
Standard_Real aU2 = aCA.LastParameter();
for (Standard_Integer i = 1; i <= Nbpt; i++)
{
Standard_Real aU = aU1 + (i - 1) * (aU2 - aU1) / (Nbpt - 1);
gp_Pnt aP = aCA.Value(aU);
aPoints.SetValue(i, aP);
aKnots.SetValue(i, aU);
aMult.SetValue(i, 1);
}
aPoints.SetValue(1, BRep_Tool::Pnt(aVFirst));
aPoints.SetValue(Nbpt, BRep_Tool::Pnt(aVLast));
aMult.SetValue(1, 2);
aMult.SetValue(Nbpt, 2);
Handle(Geom_Curve) aBSCurve = new Geom_BSplineCurve(aPoints, aKnots, aMult, 1);
GeomToStep_MakeCurve aGTSMC(aBSCurve);
aSGC = aGTSMC.Value();
}
}
if (aSGC.IsNull())
{
return Standard_False;
}
theMap.Bind(anEdge, aSGC);
theCurveList->Append(aSGC);
return Standard_True;
}
Standard_Boolean TopoDSToStep_WireframeBuilder::
GetTrimmedCurveFromFace(const TopoDS_Face& aFace,
MoniTool_DataMapOfShapeTransient& aMap,
Handle(TColStd_HSequenceOfTransient)& aCurveList) const
{
TopoDS_Shape curShape;
TopoDS_Edge curEdge;
TopExp_Explorer exp;
Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed
for (exp.Init(aFace,TopAbs_EDGE); exp.More(); exp.Next()){
curShape = exp.Current();
curEdge = TopoDS::Edge(curShape);
if (GetTrimmedCurveFromEdge(curEdge, aFace, aMap, aCurveList)) result = Standard_True;
}
return result;
}
Standard_Boolean TopoDSToStep_WireframeBuilder::
GetTrimmedCurveFromShape(const TopoDS_Shape& aShape,
MoniTool_DataMapOfShapeTransient& aMap,
Handle(TColStd_HSequenceOfTransient)& aCurveList) const
{
TopoDS_Iterator It;
Standard_Boolean result = Standard_False; //szv#4:S4163:12Mar99 `done` hid one from this, initialisation needed
//szv#4:S4163:12Mar99 optimized
switch (aShape.ShapeType()) {
case TopAbs_EDGE : {
const TopoDS_Edge& curEdge = TopoDS::Edge(aShape);
TopoDS_Face nulFace;
result = GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList);
break;
}
case TopAbs_WIRE : {
TopoDS_Face nulFace;
TopoDS_Shape curShape;
TopoDS_Edge curEdge;
TopExp_Explorer exp;
for (exp.Init(aShape,TopAbs_EDGE); exp.More(); exp.Next()){
curShape = exp.Current();
curEdge = TopoDS::Edge(curShape);
if (GetTrimmedCurveFromEdge(curEdge, nulFace, aMap, aCurveList)) result = Standard_True;
}
break;
}
case TopAbs_FACE : {
const TopoDS_Face& curFace = TopoDS::Face(aShape);
result = GetTrimmedCurveFromFace(curFace, aMap, aCurveList);
break;
}
case TopAbs_SHELL : {
TopoDS_Shell Sh = TopoDS::Shell(aShape);
It.Initialize(Sh);
for (;It.More();It.Next()) {
TopoDS_Face curFace = TopoDS::Face(It.Value());
if (GetTrimmedCurveFromFace(curFace, aMap, aCurveList)) result = Standard_True;
#ifdef OCCT_DEBUG
if(!result) {
std::cout << "ERROR extracting trimmedCurve from Face" << std::endl;
//BRepTools::Dump(curFace,std::cout); std::cout<<std::endl;
}
#endif
}
break;
}
case TopAbs_SOLID : {
It.Initialize(aShape);
for (;It.More();It.Next()) {
if (It.Value().ShapeType() == TopAbs_SHELL) {
if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True;
}
}
break;
}
case TopAbs_COMPOUND : {
It.Initialize(aShape);
for (;It.More();It.Next()) {
/* if ((It.Value().ShapeType() == TopAbs_SHELL) ||
(It.Value().ShapeType() == TopAbs_COMPOUND)) {
result = GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList);
break;
}
else if (It.Value().ShapeType() == TopAbs_FACE) {
result = GetTrimmedCurveFromFace(TopoDS::Face(It.Value()), aMap, aCurveList);
break;
} */
if (GetTrimmedCurveFromShape(It.Value(), aMap, aCurveList)) result = Standard_True;
}
break;
}
default : break;
}
return result;
}