mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
1428 lines
45 KiB
C++
1428 lines
45 KiB
C++
// Created on: 1998-07-22
|
|
// Created by: Philippe MANGIN
|
|
// Copyright (c) 1998-1999 Matra Datavision
|
|
// 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.
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <BRepFill_PipeShell.ixx>
|
|
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopTools_SequenceOfShape.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Solid.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopLoc_Location.hxx>
|
|
|
|
#include <BRepLib_MakeEdge.hxx>
|
|
#include <BRepLib_MakeFace.hxx>
|
|
#include <BRepAdaptor_HCompCurve.hxx>
|
|
#include <BRepClass3d_SolidClassifier.hxx>
|
|
|
|
#include <BRepFill.hxx>
|
|
#include <BRepFill_Sweep.hxx>
|
|
#include <BRepFill_SectionPlacement.hxx>
|
|
#include <BRepFill_Edge3DLaw.hxx>
|
|
#include <BRepFill_ACRLaw.hxx>
|
|
#include <BRepFill_EdgeOnSurfLaw.hxx>
|
|
#include <BRepFill_ShapeLaw.hxx>
|
|
#include <BRepFill_CompatibleWires.hxx>
|
|
#include <BRepFill_NSections.hxx>
|
|
#include <BRepFill_DataMapOfShapeHArray2OfShape.hxx>
|
|
#include <TColStd_HArray1OfReal.hxx>
|
|
|
|
#include <GeomFill_TrihedronLaw.hxx>
|
|
#include <GeomFill_CorrectedFrenet.hxx>
|
|
#include <GeomFill_Frenet.hxx>
|
|
#include <GeomFill_DiscreteTrihedron.hxx>
|
|
#include <GeomFill_Fixed.hxx>
|
|
#include <GeomFill_ConstantBiNormal.hxx>
|
|
#include <GeomFill_SectionLaw.hxx>
|
|
#include <GeomFill_CurveAndTrihedron.hxx>
|
|
#include <GeomFill_GuideTrihedronAC.hxx>
|
|
#include <GeomFill_GuideTrihedronPlan.hxx>
|
|
#include <GeomFill_LocationGuide.hxx>
|
|
|
|
//Specification Guide
|
|
#include <GeomAdaptor_HCurve.hxx>
|
|
|
|
#include <gp_Trsf.hxx>
|
|
#include <gp_Dir.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <Precision.hxx>
|
|
|
|
#include <Standard_NotImplemented.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <StdFail_NotDone.hxx>
|
|
|
|
#include <BRepBuilderAPI_Copy.hxx>
|
|
#include <BRepBuilderAPI_Transform.hxx>
|
|
|
|
#include <GProp_GProps.hxx>
|
|
#include <BRepGProp.hxx>
|
|
#include <GeomAdaptor_HSurface.hxx>
|
|
#include <IntCurveSurface_HInter.hxx>
|
|
#include <IntCurveSurface_IntersectionPoint.hxx>
|
|
#include <TColgp_HArray1OfPnt2d.hxx>
|
|
#include <Law_Interpol.hxx>
|
|
|
|
#ifdef DRAW
|
|
#include <Draw.hxx>
|
|
#include <DrawTrSurf.hxx>
|
|
#include <DBRep.hxx>
|
|
static Standard_Boolean Affich = 0;
|
|
#endif
|
|
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopoDS_Compound.hxx>
|
|
|
|
static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
|
|
const TopoDS_Shape& theValue,
|
|
TopTools_DataMapOfShapeListOfShape& theMap);
|
|
|
|
static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
|
|
const Handle(BRepFill_SectionLaw)& theSection,
|
|
TopoDS_Shape& theBottom,
|
|
TopoDS_Shape& theTop);
|
|
|
|
//=======================================================================
|
|
//function : ComputeSection
|
|
//purpose : Construct an intermediary section
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean ComputeSection(const TopoDS_Wire& W1,
|
|
const TopoDS_Wire& W2,
|
|
const Standard_Real p1,
|
|
const Standard_Real p2,
|
|
TopoDS_Wire& Wres)
|
|
{
|
|
TColStd_SequenceOfReal SR;
|
|
TopTools_SequenceOfShape SSh;
|
|
SR.Clear();
|
|
SR.Append(0.);
|
|
SR.Append(1.);
|
|
SSh.Clear();
|
|
SSh.Append(W1);
|
|
SSh.Append(W2);
|
|
BRepFill_CompatibleWires CW(SSh);
|
|
CW.SetPercent(0.1);
|
|
CW.Perform();
|
|
if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
|
|
GeomFill_SequenceOfTrsf EmptyTrsfs;
|
|
Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),EmptyTrsfs,SR,0.,1.);
|
|
Standard_Real US = p1/(p1+p2);
|
|
SL->D0(US, Wres);
|
|
return Standard_True;
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : PerformTransition
|
|
//purpose : Modify a law of location depending on Transition
|
|
//=======================================================================
|
|
|
|
static void PerformTransition(const BRepFill_TransitionStyle Mode,
|
|
Handle(BRepFill_LocationLaw)& Loc,
|
|
const Standard_Real angmin)
|
|
{
|
|
if (!Loc.IsNull()) {
|
|
Loc->DeleteTransform();
|
|
if (Mode == BRepFill_Modified) Loc->TransformInG0Law();
|
|
else Loc->TransformInCompatibleLaw(angmin);
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : PerformPlan
|
|
//purpose : Construct a plane of filling if exists
|
|
//=======================================================================
|
|
|
|
static Standard_Boolean PerformPlan(TopoDS_Shape& S)
|
|
{
|
|
Standard_Boolean isDegen = Standard_True;
|
|
TopExp_Explorer explo(S, TopAbs_EDGE);
|
|
for (; explo.More(); explo.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
|
|
if (!BRep_Tool::Degenerated(anEdge))
|
|
isDegen = Standard_False;
|
|
}
|
|
if (isDegen)
|
|
{
|
|
S.Nullify();
|
|
return Standard_True;
|
|
}
|
|
|
|
TopoDS_Wire W = TopoDS::Wire(S);
|
|
Standard_Boolean Ok = Standard_False;
|
|
if (!W.IsNull()) {
|
|
BRepLib_MakeFace mkplan(W, Standard_True);
|
|
if (mkplan.IsDone()) {
|
|
S = mkplan.Face();
|
|
Ok = Standard_True;
|
|
}
|
|
}
|
|
return Ok;
|
|
}
|
|
|
|
//=============================================================================
|
|
//function : IsSameOriented
|
|
//purpose : Checks whether aFace is oriented to the same side as aShell or not
|
|
//=============================================================================
|
|
|
|
static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
|
|
const TopoDS_Shape& aShell)
|
|
{
|
|
TopExp_Explorer Explo(aFace, TopAbs_EDGE);
|
|
TopoDS_Shape anEdge = Explo.Current();
|
|
TopAbs_Orientation Or1 = anEdge.Orientation();
|
|
|
|
TopTools_IndexedDataMapOfShapeListOfShape EFmap;
|
|
TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
|
|
|
|
const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
|
|
TopoDS_Shape theEdge;
|
|
for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
|
|
{
|
|
theEdge = Explo.Current();
|
|
if (theEdge.IsSame(anEdge))
|
|
break;
|
|
}
|
|
|
|
TopAbs_Orientation Or2 = theEdge.Orientation();
|
|
if (Or1 == Or2)
|
|
return Standard_False;
|
|
return Standard_True;
|
|
}
|
|
//=======================================================================
|
|
//function : BRepFill_PipeShell
|
|
//purpose :
|
|
//=======================================================================
|
|
BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
|
|
: mySpine(Spine),
|
|
myForceApproxC1(Standard_False),
|
|
myIsAutomaticLaw(Standard_False),
|
|
myTrihedron(GeomFill_IsCorrectedFrenet),
|
|
myTransition(BRepFill_Modified),
|
|
myStatus(GeomFill_PipeOk)
|
|
{
|
|
myLocation.Nullify();
|
|
mySection.Nullify();
|
|
myLaw.Nullify();
|
|
SetTolerance();
|
|
|
|
myMaxDegree = 11;
|
|
myMaxSegments = 30;
|
|
|
|
// Attention to closed non-declared wire !
|
|
if (!mySpine.Closed()) {
|
|
TopoDS_Vertex Vf, Vl;
|
|
TopExp::Vertices(mySpine, Vf, Vl);
|
|
if (Vf.IsSame(Vl)) mySpine.Closed(Standard_True);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Set
|
|
//purpose : Define a law of Frenet (Correct)
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet)
|
|
{
|
|
Handle(GeomFill_TrihedronLaw) TLaw;
|
|
if (IsFrenet) {
|
|
myTrihedron = GeomFill_IsFrenet;
|
|
TLaw = new (GeomFill_Frenet) ();
|
|
}
|
|
else {
|
|
myTrihedron = GeomFill_IsFrenet;
|
|
TLaw = new (GeomFill_CorrectedFrenet) ();
|
|
}
|
|
Handle(GeomFill_CurveAndTrihedron) Loc =
|
|
new (GeomFill_CurveAndTrihedron) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
mySection.Nullify(); //It is required to relocalize sections.
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetDiscrete
|
|
//purpose : Define a law of Discrete Trihedron
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetDiscrete()
|
|
{
|
|
Handle(GeomFill_TrihedronLaw) TLaw;
|
|
|
|
myTrihedron = GeomFill_IsDiscreteTrihedron;
|
|
TLaw = new (GeomFill_DiscreteTrihedron) ();
|
|
|
|
Handle(GeomFill_CurveAndTrihedron) Loc =
|
|
new (GeomFill_CurveAndTrihedron) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
mySection.Nullify(); //It is required to relocalize sections.
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Set
|
|
//purpose : Define a law Constant
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Set(const gp_Ax2& Axe)
|
|
{
|
|
myTrihedron = GeomFill_IsFixed;
|
|
gp_Vec V1, V2;
|
|
V1.SetXYZ(Axe.Direction().XYZ());
|
|
V2.SetXYZ(Axe.XDirection().XYZ());
|
|
Handle(GeomFill_Fixed) TLaw = new (GeomFill_Fixed) (V1, V2);
|
|
Handle(GeomFill_CurveAndTrihedron) Loc =
|
|
new (GeomFill_CurveAndTrihedron) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
mySection.Nullify(); //It is required to relocalize sections.
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Set
|
|
//purpose : Construct a law of location of binormal fixed type
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Set(const gp_Dir& BiNormal)
|
|
{
|
|
myTrihedron = GeomFill_IsConstantNormal;
|
|
|
|
Handle(GeomFill_ConstantBiNormal) TLaw =
|
|
new (GeomFill_ConstantBiNormal) (BiNormal);
|
|
Handle(GeomFill_CurveAndTrihedron) Loc =
|
|
new (GeomFill_CurveAndTrihedron) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
mySection.Nullify(); //Il faut relocaliser les sections.
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Set
|
|
//purpose : Construct a law of location of Darboux type
|
|
//=======================================================================
|
|
Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport)
|
|
{
|
|
Standard_Boolean B;
|
|
|
|
// A special law of location is required
|
|
Handle(BRepFill_EdgeOnSurfLaw) loc =
|
|
new (BRepFill_EdgeOnSurfLaw) (mySpine, SpineSupport);
|
|
B = loc->HasResult();
|
|
if (B) {
|
|
myLocation = loc;
|
|
myTrihedron = GeomFill_IsDarboux;
|
|
mySection.Nullify(); //It is required to relocalize the sections.
|
|
}
|
|
return B;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Set
|
|
//purpose : Defines a lawv with help of a guided contour
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
|
|
const Standard_Boolean CurvilinearEquivalence,
|
|
const BRepFill_TypeOfContact KeepContact)
|
|
{
|
|
// Reorganization of the guide (pb of orientation and origin)
|
|
TopoDS_Wire TheGuide;
|
|
TheGuide = AuxiliarySpine;
|
|
Standard_Boolean SpClose = mySpine.Closed(),
|
|
GuideClose = AuxiliarySpine.Closed();
|
|
|
|
if (KeepContact == BRepFill_ContactOnBorder)
|
|
myIsAutomaticLaw = Standard_True;
|
|
|
|
if (!SpClose && !GuideClose) {
|
|
// Case open reorientation of the guide
|
|
TopoDS_Wire sp = mySpine;
|
|
TopTools_SequenceOfShape Seq;
|
|
Seq.Append(sp);
|
|
Seq.Append(TheGuide);
|
|
BRepFill_CompatibleWires CW(Seq);
|
|
CW.SetPercent(0.1);
|
|
CW.Perform();
|
|
if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
|
|
TheGuide = TopoDS::Wire(CW.Shape().Value(2));
|
|
}
|
|
else if (GuideClose) {
|
|
// Case guide closed : Determination of the origin
|
|
// & reorientation of the guide
|
|
gp_Vec Dir;
|
|
gp_Pnt SpOr;
|
|
if (!SpClose) {
|
|
TopoDS_Vertex Vf, Vl;
|
|
gp_Pnt P;
|
|
TopExp::Vertices(mySpine, Vf, Vl);
|
|
SpOr = BRep_Tool::Pnt(Vf);
|
|
P = BRep_Tool::Pnt(Vl);
|
|
gp_Vec V(P, SpOr);
|
|
SpOr.BaryCenter(0.5, P, 0.5);
|
|
Dir = V;
|
|
}
|
|
else {
|
|
BRepAdaptor_CompCurve BC(mySpine);
|
|
BC.D1(0,SpOr,Dir);
|
|
}
|
|
BRepFill::SearchOrigin(TheGuide, SpOr, Dir, 100*myTol3d);
|
|
}
|
|
|
|
#ifdef DRAW
|
|
if (Affich)
|
|
DBRep::Set("theguide", TheGuide);
|
|
#endif
|
|
// transform the guide in a single curve (periodic if posssible)
|
|
Handle(BRepAdaptor_HCompCurve) Guide =
|
|
new (BRepAdaptor_HCompCurve) (TheGuide);
|
|
Guide->ChangeCurve().SetPeriodic(Standard_True);
|
|
|
|
if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
|
|
if (KeepContact == BRepFill_Contact ||
|
|
KeepContact == BRepFill_ContactOnBorder)
|
|
myTrihedron = GeomFill_IsGuideACWithContact; // with rotation
|
|
else
|
|
myTrihedron = GeomFill_IsGuideAC; // without rotation
|
|
|
|
Handle(GeomFill_GuideTrihedronAC) TLaw
|
|
= new (GeomFill_GuideTrihedronAC) (Guide);
|
|
Handle(GeomFill_LocationGuide) Loc =
|
|
new (GeomFill_LocationGuide) (TLaw);
|
|
myLocation = new (BRepFill_ACRLaw) (mySpine, Loc);
|
|
}
|
|
else {// trihedron by plane
|
|
if (KeepContact == BRepFill_Contact ||
|
|
KeepContact == BRepFill_ContactOnBorder)
|
|
myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation
|
|
else
|
|
myTrihedron = GeomFill_IsGuidePlan; // without rotation
|
|
|
|
Handle(GeomFill_GuideTrihedronPlan) TLaw =
|
|
new (GeomFill_GuideTrihedronPlan) (Guide);
|
|
Handle(GeomFill_LocationGuide) Loc =
|
|
new (GeomFill_LocationGuide) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
}
|
|
mySection.Nullify(); //It is required to relocalize the sections.
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetMaxDegree
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetMaxDegree(const Standard_Integer NewMaxDegree)
|
|
{
|
|
myMaxDegree = NewMaxDegree;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetMaxSegments
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetMaxSegments(const Standard_Integer NewMaxSegments)
|
|
{
|
|
myMaxSegments = NewMaxSegments;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetForceApproxC1
|
|
//purpose : Set the flag that indicates attempt to approximate
|
|
// a C1-continuous surface if a swept surface proved
|
|
// to be C0.
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
|
|
{
|
|
myForceApproxC1 = ForceApproxC1;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Add
|
|
//purpose : Add a Section
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
|
|
const Standard_Boolean WithContact,
|
|
const Standard_Boolean WithCorrection)
|
|
{
|
|
TopoDS_Vertex V;
|
|
V.Nullify();
|
|
Add(Profile, V, WithContact, WithCorrection);
|
|
ResetLoc();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Add
|
|
//purpose : Add a Section
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
|
|
const TopoDS_Vertex& Location,
|
|
const Standard_Boolean WithContact,
|
|
const Standard_Boolean WithCorrection)
|
|
{
|
|
Delete(Profile); // No duplication
|
|
if (myIsAutomaticLaw)
|
|
{
|
|
mySeq.Clear();
|
|
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
|
|
S.Set(Standard_True);
|
|
mySeq.Append(S);
|
|
mySection.Nullify();
|
|
ResetLoc();
|
|
|
|
Handle(GeomFill_LocationGuide) Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(1));
|
|
Handle(TColgp_HArray1OfPnt2d) ParAndRad;
|
|
Loc->ComputeAutomaticLaw(ParAndRad);
|
|
|
|
//Compuite initial width of section (this will be 1.)
|
|
GProp_GProps GlobalProps;
|
|
BRepGProp::LinearProperties(Profile, GlobalProps);
|
|
gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
|
|
|
|
TopoDS_Face ProfileFace = BRepLib_MakeFace(TopoDS::Wire(Profile), Standard_True); //only plane
|
|
Handle(Geom_Surface) thePlane = BRep_Tool::Surface(ProfileFace);
|
|
Handle(GeomAdaptor_HSurface) GAHplane = new GeomAdaptor_HSurface(thePlane);
|
|
IntCurveSurface_HInter Intersector;
|
|
Handle(Adaptor3d_HCurve) aHCurve [2];
|
|
aHCurve[0] = Loc->GetCurve();
|
|
aHCurve[1] = Loc->Guide();
|
|
gp_Pnt PointsOnSpines [2];
|
|
Standard_Integer i, j;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
Intersector.Perform(aHCurve[i], GAHplane);
|
|
Standard_Real MinDist = RealLast();
|
|
for (j = 1; j <= Intersector.NbPoints(); j++)
|
|
{
|
|
gp_Pnt aPint = Intersector.Point(j).Pnt();
|
|
Standard_Real aDist = BaryCenter.Distance(aPint);
|
|
if (aDist < MinDist)
|
|
{
|
|
MinDist = aDist;
|
|
PointsOnSpines[i] = aPint;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Correct <ParAndRad> according to <InitialWidth>
|
|
Standard_Real InitialWidth = PointsOnSpines[0].Distance(PointsOnSpines[1]);
|
|
Standard_Integer NbParRad = ParAndRad->Upper();
|
|
for (i = 1; i <= NbParRad; i++)
|
|
{
|
|
gp_Pnt2d aParRad = ParAndRad->Value(i);
|
|
aParRad.SetY( aParRad.Y() / InitialWidth );
|
|
ParAndRad->SetValue(i, aParRad);
|
|
}
|
|
|
|
myLaw = new Law_Interpol();
|
|
|
|
Standard_Boolean IsPeriodic =
|
|
(Abs(ParAndRad->Value(1).Y() - ParAndRad->Value(NbParRad).Y()) < Precision::Confusion());
|
|
|
|
(Handle(Law_Interpol)::DownCast(myLaw))->Set(ParAndRad->Array1(), IsPeriodic);
|
|
}
|
|
else
|
|
{
|
|
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
|
|
mySeq.Append(S);
|
|
mySection.Nullify();
|
|
ResetLoc();
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetLaw
|
|
//purpose : Section + law of homothety
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
|
|
const Handle(Law_Function)& L,
|
|
const Standard_Boolean WithContact,
|
|
const Standard_Boolean WithCorrection)
|
|
{
|
|
TopoDS_Vertex V;
|
|
V.Nullify();
|
|
SetLaw( Profile, L, V, WithContact, WithCorrection);
|
|
ResetLoc();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetLaw
|
|
//purpose : Section + Law of homothety
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
|
|
const Handle(Law_Function)& L,
|
|
const TopoDS_Vertex& Location,
|
|
const Standard_Boolean WithContact,
|
|
const Standard_Boolean WithCorrection)
|
|
{
|
|
mySeq.Clear();
|
|
BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
|
|
S.Set(Standard_True);
|
|
mySeq.Append(S);
|
|
myLaw = L;
|
|
mySection.Nullify();
|
|
ResetLoc();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Delete
|
|
//purpose : Delete a section
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile)
|
|
{
|
|
Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
|
|
|
|
Standard_Boolean Trouve=Standard_False;
|
|
Standard_Integer ii;
|
|
for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
|
|
Standard_Boolean found = Standard_False;
|
|
const TopoDS_Wire& aWire = mySeq.Value(ii).Wire();
|
|
if (isVertex)
|
|
{
|
|
TopExp_Explorer Explo(aWire, TopAbs_VERTEX);
|
|
for (; Explo.More(); Explo.Next())
|
|
if (Profile.IsSame(Explo.Current()))
|
|
found = Standard_True;
|
|
}
|
|
else if (Profile.IsSame(aWire))
|
|
found = Standard_True;
|
|
|
|
if (found)
|
|
{
|
|
Trouve = Standard_True;
|
|
mySeq.Remove(ii);
|
|
}
|
|
}
|
|
|
|
if (Trouve) mySection.Nullify();
|
|
ResetLoc();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsReady
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean BRepFill_PipeShell::IsReady() const
|
|
{
|
|
return (mySeq.Length() != 0);
|
|
}
|
|
//=======================================================================
|
|
//function : GetStatus
|
|
//purpose :
|
|
//=======================================================================
|
|
GeomFill_PipeError BRepFill_PipeShell::GetStatus() const
|
|
{
|
|
return myStatus;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : SetTolerance
|
|
//purpose :
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d ,
|
|
const Standard_Real BoundTol,
|
|
const Standard_Real TolAngular)
|
|
{
|
|
myTol3d = Tol3d;
|
|
myBoundTol = BoundTol;
|
|
myTolAngular = TolAngular;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetTransition
|
|
//purpose : Defines the mode of processing of corners
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode,
|
|
const Standard_Real Angmin,
|
|
const Standard_Real Angmax)
|
|
{
|
|
if (myTransition != Mode)
|
|
mySection.Nullify(); //It is required to relocalize the sections.
|
|
myTransition = Mode;
|
|
angmin = Angmin;
|
|
angmax = Angmax;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Simulate
|
|
//purpose : Calculate N Sections
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Simulate(const Standard_Integer N,
|
|
TopTools_ListOfShape& List)
|
|
{
|
|
// Preparation
|
|
Prepare();
|
|
List.Clear();
|
|
|
|
Standard_Real First, Last, Length, Delta, U,
|
|
US, DeltaS,FirstS;
|
|
Standard_Integer ii, NbL = myLocation->NbLaw();
|
|
Standard_Boolean Finis=Standard_False;
|
|
TopoDS_Shape W;
|
|
|
|
// Calculate the parameters of digitalization
|
|
mySection->Law(1)->GetDomain(FirstS, Last);
|
|
DeltaS = Last - FirstS;
|
|
myLocation->CurvilinearBounds(NbL,First, Length);
|
|
Delta = Length;
|
|
if (N>1) Delta /= (N-1);
|
|
|
|
myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last
|
|
for (U=0.0, ii=1; !Finis ; U+=Delta) {
|
|
if (U >= Length) {
|
|
U = Length;
|
|
Finis = Standard_True;
|
|
}
|
|
else {
|
|
if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last);
|
|
if (U > Last) U = (Last+First)/2; // The edge is not skipped
|
|
if (U> First) ii++;
|
|
}
|
|
US = FirstS + (U/Length)*DeltaS;
|
|
// Calcul d'une section
|
|
mySection->D0(US, W);
|
|
myLocation->D0(U, W);
|
|
List.Append(W);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Build
|
|
//purpose : Construct the Shell and the history
|
|
//=======================================================================
|
|
Standard_Boolean BRepFill_PipeShell::Build()
|
|
{
|
|
Standard_Boolean Ok;
|
|
Standard_Real FirstS, LastS;
|
|
// 1) Preparation
|
|
Prepare();
|
|
|
|
if (myStatus != GeomFill_PipeOk) {
|
|
BRep_Builder B;
|
|
TopoDS_Shell Sh;
|
|
B.MakeShell(Sh);
|
|
myShape = Sh; // Nullify
|
|
return Standard_False;
|
|
}
|
|
|
|
// 2) Calculate myFirst and myLast
|
|
mySection->Law(1)->GetDomain(FirstS, LastS);
|
|
mySection->D0(FirstS, myFirst);
|
|
myLocation->D0(0, myFirst);
|
|
if (mySection->IsVClosed() && myLocation->IsClosed()) {
|
|
if (myLocation->IsG1(0)>=0)
|
|
myLast = myFirst;
|
|
else {
|
|
myFirst.Nullify();
|
|
myLast.Nullify();
|
|
}
|
|
}
|
|
else {
|
|
Standard_Real Length;
|
|
myLocation->CurvilinearBounds(myLocation->NbLaw(),
|
|
FirstS, Length);
|
|
mySection->D0(LastS, myLast);
|
|
myLocation->D0(Length, myLast);
|
|
// eap 5 Jun 2002 occ332, myLast and myFirst must not share one TShape,
|
|
// tolerances of shapes built on them may be quite different
|
|
if (myFirst.IsPartner( myLast )) {
|
|
BRepBuilderAPI_Copy copy(myLast);
|
|
if (copy.IsDone())
|
|
myLast = copy.Shape();
|
|
}
|
|
// eap 5 Jun 2002 occ332, end modif
|
|
}
|
|
#if DRAW
|
|
if (Affich) {
|
|
DBRep::Set("PipeFirst", myFirst);
|
|
DBRep::Set("PipeLast", myLast);
|
|
}
|
|
#endif
|
|
|
|
// 3) Construction
|
|
BRepFill_Sweep MkSw(mySection, myLocation, Standard_True);
|
|
MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
|
|
MkSw.SetAngularControl(angmin, angmax);
|
|
MkSw.SetForceApproxC1(myForceApproxC1);
|
|
MkSw.SetBounds(TopoDS::Wire(myFirst),
|
|
TopoDS::Wire(myLast));
|
|
GeomAbs_Shape theContinuity = GeomAbs_C2;
|
|
if (myTrihedron == GeomFill_IsDiscreteTrihedron)
|
|
theContinuity = GeomAbs_C0;
|
|
TopTools_MapOfShape Dummy;
|
|
BRepFill_DataMapOfShapeHArray2OfShape Dummy2;
|
|
BRepFill_DataMapOfShapeHArray2OfShape Dummy3;
|
|
MkSw.Build(Dummy, Dummy2, Dummy3, myTransition, theContinuity,
|
|
GeomFill_Location, myMaxDegree, myMaxSegments);
|
|
|
|
myStatus = myLocation->GetStatus();
|
|
Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));
|
|
|
|
if (Ok) {
|
|
myShape = MkSw.Shape();
|
|
myErrorOnSurf = MkSw.ErrorOnSurface();
|
|
|
|
TopoDS_Shape aBottomWire = myFirst;
|
|
TopoDS_Shape aTopWire = myLast;
|
|
|
|
if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) {
|
|
myFirst = aBottomWire;
|
|
myLast = aTopWire;
|
|
}
|
|
|
|
if (mySection->IsUClosed())
|
|
{
|
|
TopExp_Explorer explo;
|
|
Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True;
|
|
|
|
for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
|
|
DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge);
|
|
}
|
|
|
|
for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
|
|
DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge);
|
|
}
|
|
|
|
if (DegenFirst && DegenLast)
|
|
myShape.Closed(Standard_True);
|
|
}
|
|
|
|
BuildHistory(MkSw);
|
|
}
|
|
else {
|
|
BRep_Builder B;
|
|
TopoDS_Shell Sh;
|
|
B.MakeShell(Sh);
|
|
myShape = Sh; // Nullify
|
|
if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk;
|
|
}
|
|
return Ok;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MakeSolid
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean BRepFill_PipeShell::MakeSolid()
|
|
{
|
|
if (myShape.IsNull())
|
|
StdFail_NotDone::Raise("PipeShell is not built");
|
|
Standard_Boolean B = myShape.Closed();
|
|
BRep_Builder BS;
|
|
|
|
if (!B)
|
|
{
|
|
if(!myFirst.IsNull() && !myLast.IsNull()) {
|
|
B = (myFirst.Closed() && myLast.Closed());
|
|
}
|
|
if (B) {
|
|
// It is necessary to block the extremities
|
|
B = PerformPlan(myFirst);
|
|
if (B) {
|
|
B = PerformPlan(myLast);
|
|
if (B) {
|
|
if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape ))
|
|
myFirst.Reverse();
|
|
if (!myLast.IsNull() && !IsSameOriented( myLast, myShape ))
|
|
myLast.Reverse();
|
|
|
|
if (!myFirst.IsNull())
|
|
BS.Add(myShape, TopoDS::Face(myFirst));
|
|
if (!myLast.IsNull())
|
|
BS.Add(myShape, TopoDS::Face(myLast));
|
|
|
|
myShape.Closed(Standard_True);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (B) {
|
|
TopoDS_Solid solid;
|
|
BS.MakeSolid(solid);
|
|
BS.Add(solid,TopoDS::Shell(myShape));
|
|
BRepClass3d_SolidClassifier SC(solid);
|
|
SC.PerformInfinitePoint(Precision::Confusion());
|
|
if ( SC.State() == TopAbs_IN) {
|
|
BS.MakeSolid(solid);
|
|
myShape.Reverse();
|
|
BS.Add(solid,TopoDS::Shell(myShape));
|
|
}
|
|
myShape = solid;
|
|
myShape.Closed(Standard_True);
|
|
}
|
|
return B;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Shape
|
|
//purpose : Return the result
|
|
//=======================================================================
|
|
const TopoDS_Shape& BRepFill_PipeShell::Shape() const
|
|
{
|
|
return myShape;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ErrorOnSurface
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Real BRepFill_PipeShell::ErrorOnSurface() const
|
|
{
|
|
return myErrorOnSurf;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FirstShape
|
|
//purpose : Return the start section
|
|
//=======================================================================
|
|
const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const
|
|
{
|
|
return myFirst;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : LastShape
|
|
//purpose : Return the end section
|
|
//=======================================================================
|
|
const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
|
|
{
|
|
return myLast;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Generated
|
|
//purpose :
|
|
//=======================================================================
|
|
// void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
|
|
// TopTools_ListOfShape& )
|
|
void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape,
|
|
TopTools_ListOfShape& theList)
|
|
{
|
|
// Standard_NotImplemented::Raise("Generated:Pas Fait");
|
|
theList.Clear();
|
|
|
|
if(myGenMap.IsBound(theShape)) {
|
|
theList = myGenMap.Find(theShape);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Prepare
|
|
//purpose : - Check that everything is ready
|
|
// - Construct the law of section
|
|
// - Construct the law of location if required
|
|
// - Calculate First & Last
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Prepare()
|
|
{
|
|
TopoDS_Wire theSect;
|
|
if (!IsReady()) StdFail_NotDone::Raise("PipeShell");
|
|
if (!myLocation.IsNull() && !mySection.IsNull()) return; // It is ready
|
|
|
|
//Check set of section for right configuration of punctual sections
|
|
Standard_Integer i;
|
|
TopoDS_Iterator iter;;
|
|
for (i = 2; i <= mySeq.Length()-1; i++)
|
|
{
|
|
Standard_Boolean wdeg = Standard_True;
|
|
for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
|
|
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
|
|
}
|
|
if (wdeg)
|
|
Standard_Failure::Raise("Wrong usage of punctual sections");
|
|
}
|
|
if (mySeq.Length() <= 2)
|
|
{
|
|
Standard_Boolean wdeg = Standard_True;
|
|
for (i = 1; i <= mySeq.Length(); i++)
|
|
for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next())
|
|
{
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
|
|
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
|
|
}
|
|
if (wdeg)
|
|
Standard_Failure::Raise("Wrong usage of punctual sections");
|
|
}
|
|
|
|
// Construction of the law of location
|
|
if(myLocation.IsNull())
|
|
{
|
|
switch(myTrihedron)
|
|
{
|
|
case GeomFill_IsCorrectedFrenet :
|
|
{
|
|
Handle(GeomFill_TrihedronLaw) TLaw =
|
|
new (GeomFill_CorrectedFrenet) ();
|
|
Handle(GeomFill_CurveAndTrihedron) Loc =
|
|
new (GeomFill_CurveAndTrihedron) (TLaw);
|
|
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
|
|
break;
|
|
}
|
|
default :
|
|
{ // Not planned!
|
|
Standard_ConstructionError::Raise("PipeShell");
|
|
}
|
|
}
|
|
}
|
|
|
|
//Transformation of the law (Transition Management)
|
|
PerformTransition(myTransition, myLocation, angmin);
|
|
|
|
|
|
// Construction of the section law
|
|
if (mySeq.Length() == 1) {
|
|
Standard_Real p1;
|
|
gp_Trsf aTrsf;
|
|
Place(mySeq(1), theSect, aTrsf, p1);
|
|
TopoDS_Wire aLocalShape = theSect;
|
|
if (mySeq(1).IsLaw())
|
|
mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw);
|
|
// mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw);
|
|
else
|
|
mySection = new BRepFill_ShapeLaw(aLocalShape);
|
|
// mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect));
|
|
}
|
|
else
|
|
{
|
|
TColStd_SequenceOfReal Param;
|
|
TopTools_SequenceOfShape WSeq;
|
|
GeomFill_SequenceOfTrsf Transformations;
|
|
//WSeq.Clear();
|
|
//Param.Clear();
|
|
Standard_Integer NbL = myLocation->NbLaw();
|
|
gp_Trsf aTrsf;
|
|
Standard_Real V1, V2, param;
|
|
myLocation->CurvilinearBounds(NbL, V1, V2);
|
|
V1 = 0.;
|
|
Standard_Integer ideb = 0, ifin = 0;
|
|
// for (Standard_Integer iseq=1;iseq<=mySeq.Length();iseq++) {
|
|
Standard_Integer iseq;
|
|
for (iseq=1;iseq<=mySeq.Length();iseq++) {
|
|
Place(mySeq(iseq), theSect, aTrsf, param);
|
|
Param.Append(param);
|
|
WSeq.Append(theSect);
|
|
// WSeq.Append(TopoDS::Wire(theSect));
|
|
Transformations.Append(aTrsf);
|
|
if (param==V1) ideb = iseq;
|
|
if (param==V2) ifin = iseq;
|
|
}
|
|
|
|
|
|
// looping sections ?
|
|
if (myLocation->IsClosed()) {
|
|
if (ideb>0) {
|
|
// place the initial section at the final position
|
|
Param.Append(V2);
|
|
WSeq.Append(WSeq(ideb));
|
|
}
|
|
else if (ifin>0) {
|
|
// place the final section at the initial position
|
|
Param.Append(V1);
|
|
WSeq.Append(WSeq(ifin));
|
|
}
|
|
else {
|
|
// it is necessary to find a medium section to impose by V1 and by V2
|
|
Standard_Real pmin = Param.Value(1), pmax = Param.Value(1);
|
|
TopoDS_Wire Wmin = TopoDS::Wire(WSeq.Value(1)), Wmax;
|
|
for (iseq=2;iseq<=WSeq.Length();iseq++) {
|
|
if (Param.Value(iseq)<pmin) {
|
|
pmin = Param.Value(iseq);
|
|
Wmin = TopoDS::Wire(WSeq.Value(iseq));
|
|
}
|
|
if (Param.Value(iseq)>pmax) {
|
|
pmax = Param.Value(iseq);
|
|
Wmax = TopoDS::Wire(WSeq.Value(iseq));
|
|
}
|
|
}
|
|
// medium section between Wmin and Wmax
|
|
TopoDS_Wire Wres;
|
|
Standard_Real dmin = Abs(pmin-V1);
|
|
Standard_Real dmax = Abs(pmax-V2);
|
|
if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) {
|
|
// impose section Wres at the beginning and the end
|
|
Param.Append(V1);
|
|
WSeq.Append(Wres);
|
|
Param.Append(V2);
|
|
WSeq.Append(Wres);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// parse sections by increasing parameter
|
|
Standard_Boolean play_again = Standard_True;
|
|
while (play_again) {
|
|
play_again = Standard_False;
|
|
for (iseq=1;iseq<=WSeq.Length();iseq++) {
|
|
for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) {
|
|
if (Param.Value(iseq)>Param.Value(jseq)) {
|
|
Param.Exchange(iseq,jseq);
|
|
WSeq.Exchange(iseq,jseq);
|
|
play_again = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef DRAW
|
|
if ( Affich) {
|
|
char* name = new char[100];
|
|
Standard_Integer NBSECT = 0;
|
|
for (Standard_Integer i=1;i<=WSeq.Length();i++) {
|
|
NBSECT++;
|
|
sprintf(name,"WSeq_%d",NBSECT);
|
|
DBRep::Set(name,TopoDS::Wire(WSeq.Value(i)));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
// Calculate work sections
|
|
TopTools_SequenceOfShape WorkingSections;
|
|
WorkingSections.Clear();
|
|
TopTools_DataMapOfShapeListOfShape WorkingMap;
|
|
WorkingMap.Clear();
|
|
BRepFill_CompatibleWires Georges(WSeq);
|
|
Georges.SetPercent(0.1);
|
|
Georges.Perform(Standard_False);
|
|
if (Georges.IsDone()) {
|
|
WorkingSections = Georges.Shape();
|
|
WorkingMap = Georges.Generated();
|
|
}
|
|
else {
|
|
Standard_ConstructionError::Raise("PipeShell : uncompatible wires");
|
|
}
|
|
mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2);
|
|
|
|
}// else
|
|
|
|
// modify the law of location if contact
|
|
if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
|
|
|| (myTrihedron == GeomFill_IsGuideACWithContact) ) {
|
|
Standard_Real fs, f, l, Delta, Length;
|
|
Handle(GeomFill_LocationGuide) Loc;
|
|
Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw();
|
|
myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length);
|
|
Sec->GetDomain(fs,l);
|
|
Delta = (l-fs)/Length;
|
|
|
|
Standard_Real angle, old_angle = 0;
|
|
for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) {
|
|
myLocation->CurvilinearBounds(ipath, f, l);
|
|
Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath));
|
|
Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta,
|
|
old_angle, angle); // force the rotation
|
|
old_angle = angle;
|
|
}
|
|
}
|
|
|
|
myStatus = myLocation->GetStatus();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Place
|
|
//purpose : Implement a Section in the local refernce frame
|
|
// and return its parameter on the trajectory
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
|
|
TopoDS_Wire& W,
|
|
gp_Trsf& aTrsf,
|
|
Standard_Real& param)
|
|
{
|
|
BRepFill_SectionPlacement Place(myLocation,
|
|
Sec.Wire(),
|
|
Sec.Vertex(),
|
|
Sec.WithContact(),
|
|
Sec.WithCorrection());
|
|
TopoDS_Wire TmpWire = Sec.Wire();
|
|
aTrsf = Place.Transformation();
|
|
//TopLoc_Location Loc2(Place.Transformation()), Loc1;
|
|
//Loc1 = TmpWire.Location();
|
|
//W.Location(Loc2.Multiplied(Loc1));
|
|
//Transform the copy
|
|
W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True));
|
|
////////////////////////////////////
|
|
param = Place.AbscissaOnPath();
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : ResetLoc
|
|
//purpose : Remove references to the sections in the laws of location
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::ResetLoc()
|
|
{
|
|
if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
|
|
|| (myTrihedron == GeomFill_IsGuideACWithContact) ) {
|
|
Handle(GeomFill_LocationGuide) Loc;
|
|
for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) {
|
|
Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec));
|
|
Loc->EraseRotation();// remove the rotation
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BuildHistory
|
|
//purpose : Builds history for edges of spine,
|
|
// for built bottom shape of sweep,
|
|
// for boundary vertices of bottom shape of sweep,
|
|
// for boundary profiles
|
|
//=======================================================================
|
|
void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
|
|
{
|
|
Handle(TopTools_HArray2OfShape) aFaces = theSweep.SubShape();
|
|
Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
|
|
Handle(TopTools_HArray2OfShape) aUEdges = theSweep.InterFaces();
|
|
Standard_Integer i = 0, j = 0;
|
|
Standard_Boolean bPrevModified = Standard_False;
|
|
|
|
for(i = 1; i <= mySection->NbLaw(); i++) {
|
|
if((!aVEdges->Value(i, 1).IsNull()) && (aVEdges->Value(i, 1).ShapeType() == TopAbs_FACE)) {
|
|
bPrevModified = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for(j = myLocation->NbLaw(); j >= 1; j--) {
|
|
TopTools_ListOfShape aListOfFace;
|
|
|
|
if(bPrevModified) {
|
|
for(i = 1; i <= mySection->NbLaw(); i++) {
|
|
Standard_Integer lessindex = j + 1;
|
|
lessindex = (lessindex > myLocation->NbLaw()) ? 1 : lessindex;
|
|
|
|
if((!aVEdges->Value(i, lessindex).IsNull()) && (aVEdges->Value(i, lessindex).ShapeType() == TopAbs_FACE)) {
|
|
aListOfFace.Append(aVEdges->Value(i, lessindex));
|
|
const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
|
|
|
|
if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
|
|
UpdateMap(aBottomEdge, aVEdges->Value(i, lessindex), myGenMap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bPrevModified = Standard_False;
|
|
|
|
for(i = 1; i <= mySection->NbLaw(); i++) {
|
|
if((!aVEdges->Value(i, j).IsNull()) && (aVEdges->Value(i, j).ShapeType() == TopAbs_FACE)) {
|
|
aListOfFace.Append(aVEdges->Value(i, j));
|
|
bPrevModified = Standard_True;
|
|
|
|
const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
|
|
|
|
if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
|
|
UpdateMap(aBottomEdge, aVEdges->Value(i, j), myGenMap);
|
|
}
|
|
}
|
|
|
|
if(aFaces->Value(i, j).ShapeType() == TopAbs_FACE) {
|
|
aListOfFace.Append(aFaces->Value(i, j));
|
|
const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
|
|
|
|
if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
|
|
UpdateMap(aBottomEdge, aFaces->Value(i, j), myGenMap);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!myGenMap.IsBound(myLocation->Edge(j)))
|
|
myGenMap.Bind(myLocation->Edge(j), aListOfFace);
|
|
else
|
|
myGenMap.ChangeFind(myLocation->Edge(j)).Append(aListOfFace);
|
|
|
|
// build history for free booundaries.begin
|
|
if(!mySection->IsUClosed()) {
|
|
TopoDS_Compound aFaceComp;
|
|
BRep_Builder aB;
|
|
aB.MakeCompound(aFaceComp);
|
|
TopTools_ListIteratorOfListOfShape anIt(aListOfFace);
|
|
|
|
for(; anIt.More(); anIt.Next()) {
|
|
aB.Add(aFaceComp, anIt.Value());
|
|
}
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
|
|
TopExp::MapShapesAndAncestors(aFaceComp, TopAbs_EDGE, TopAbs_FACE, aMapEF);
|
|
Standard_Integer eit = 0;
|
|
|
|
for(eit = aUEdges->LowerRow(); eit <= aUEdges->UpperRow(); eit++) {
|
|
const TopoDS_Shape& aShape = aUEdges->Value(eit, j);
|
|
|
|
if(aMapEF.Contains(aShape)) {
|
|
const TopTools_ListOfShape& aList = aMapEF.FindFromKey(aShape);
|
|
|
|
if(aList.Extent() < 2) {
|
|
UpdateMap(myLocation->Edge(j), aShape, myGenMap);
|
|
|
|
TopoDS_Shape aGenVertex;
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
|
|
|
|
for(i = 1; i <= mySection->NbLaw(); i++) {
|
|
const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
|
|
|
|
if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
|
|
TopExp::MapShapesAndAncestors(aBottomEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
|
|
}
|
|
}
|
|
const TopoDS_Shape& aFreeEdge = aUEdges->Value(eit, aUEdges->LowerCol());
|
|
TopExp::MapShapesAndAncestors(aFreeEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
|
|
TopExp_Explorer anExpV(aFreeEdge, TopAbs_VERTEX);
|
|
|
|
for(; anExpV.More(); anExpV.Next()) {
|
|
if(aMapVE.Contains(anExpV.Current())) {
|
|
const TopTools_ListOfShape& aListOfV = aMapVE.FindFromKey(anExpV.Current());
|
|
|
|
if(aListOfV.Extent() >= 2) {
|
|
aGenVertex = anExpV.Current();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!aGenVertex.IsNull()) {
|
|
UpdateMap(aGenVertex, aShape, myGenMap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// end for(eit = aUEdges->LowerRow...
|
|
}
|
|
// build history for free booundaries.end
|
|
}
|
|
|
|
// build history for boundary section wires. begin
|
|
|
|
if(!mySeq.IsEmpty()) {
|
|
Standard_Integer iseq;
|
|
TopoDS_Wire aSect;
|
|
gp_Trsf aTrsf;
|
|
Standard_Real param = 0., aparmin = RealLast(), aparmax = -RealLast();
|
|
Standard_Integer ideb = 1, ifin = mySeq.Length();
|
|
|
|
for (iseq = 1;iseq <= mySeq.Length(); iseq++) {
|
|
Place(mySeq(iseq), aSect, aTrsf, param);
|
|
|
|
if(param < aparmin) {
|
|
ideb = iseq;
|
|
aparmin = param;
|
|
}
|
|
|
|
if(param > aparmax) {
|
|
ifin = iseq;
|
|
aparmax = param;
|
|
}
|
|
}
|
|
|
|
UpdateMap(mySeq(ideb).Wire(), myFirst, myGenMap);
|
|
UpdateMap(mySeq(ifin).Wire(), myLast, myGenMap);
|
|
}
|
|
// build history for boundary section wires. end
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------
|
|
// static function: UpdateMap
|
|
// purpose:
|
|
// ---------------------------------------------------------------------------------
|
|
Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
|
|
const TopoDS_Shape& theValue,
|
|
TopTools_DataMapOfShapeListOfShape& theMap) {
|
|
|
|
if(!theMap.IsBound(theKey)) {
|
|
TopTools_ListOfShape thelist;
|
|
theMap.Bind(theKey, thelist);
|
|
}
|
|
TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
|
|
TopTools_ListIteratorOfListOfShape anIt(aList);
|
|
Standard_Boolean found = Standard_False;
|
|
|
|
for(; anIt.More(); anIt.Next()) {
|
|
if(theValue.IsSame(anIt.Value())) {
|
|
found = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!found)
|
|
aList.Append(theValue);
|
|
return !found;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------
|
|
// static function: BuildBoundaries
|
|
// purpose:
|
|
// ---------------------------------------------------------------------------------
|
|
Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
|
|
const Handle(BRepFill_SectionLaw)& theSection,
|
|
TopoDS_Shape& theBottom,
|
|
TopoDS_Shape& theTop) {
|
|
|
|
TopoDS_Wire aBottomWire;
|
|
TopoDS_Wire aTopWire;
|
|
BRep_Builder aB;
|
|
aB.MakeWire(aBottomWire);
|
|
aB.MakeWire(aTopWire);
|
|
Standard_Boolean bfoundbottom = Standard_False;
|
|
Standard_Boolean bfoundtop = Standard_False;
|
|
Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
|
|
Standard_Integer i = 0;
|
|
Standard_Boolean bAllSame = Standard_True;
|
|
|
|
for(i = 1; i <= theSection->NbLaw(); i++) {
|
|
const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
|
|
|
|
if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
|
|
aB.Add(aBottomWire, aBottomEdge);
|
|
bfoundbottom = Standard_True;
|
|
}
|
|
const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol());
|
|
|
|
if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) {
|
|
aB.Add(aTopWire, aTopEdge);
|
|
bfoundtop = Standard_True;
|
|
}
|
|
|
|
if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge))
|
|
bAllSame = Standard_False;
|
|
}
|
|
|
|
if(theSection->IsUClosed()) {
|
|
aBottomWire.Closed(Standard_True);
|
|
aTopWire.Closed(Standard_True);
|
|
}
|
|
|
|
if(bfoundbottom) {
|
|
theBottom = aBottomWire;
|
|
}
|
|
|
|
if(bfoundtop) {
|
|
theTop = aTopWire;
|
|
}
|
|
|
|
if(bAllSame && bfoundbottom && bfoundtop)
|
|
theTop = theBottom;
|
|
|
|
return bfoundbottom || bfoundtop;
|
|
}
|