-// File: BRepFill_PipeShell.cxx
-// Created: Wed Jul 22 10:52:44 1998
-// Author: Philippe MANGIN
-// <pmn@sgi29>
+// 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 <BRepBuilderAPI_Copy.hxx>
+#include <BRepBuilderAPI_Transform.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_DataMapOfShapeHArray2OfShape.hxx>
+#include <BRepFill_Edge3DLaw.hxx>
+#include <BRepFill_EdgeOnSurfLaw.hxx>
+#include <BRepFill_LocationLaw.hxx>
#include <BRepFill_NSections.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-
-#include <GeomFill_TrihedronLaw.hxx>
-#include <GeomFill_CorrectedFrenet.hxx>
-#include <GeomFill_Frenet.hxx>
-#include <GeomFill_Fixed.hxx>
+#include <BRepFill_PipeShell.hxx>
+#include <BRepFill_Section.hxx>
+#include <BRepFill_SectionLaw.hxx>
+#include <BRepFill_SectionPlacement.hxx>
+#include <BRepFill_ShapeLaw.hxx>
+#include <BRepFill_Sweep.hxx>
+#include <BRepGProp.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
#include <GeomFill_ConstantBiNormal.hxx>
-#include <GeomFill_SectionLaw.hxx>
+#include <GeomFill_CorrectedFrenet.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
+#include <GeomFill_DiscreteTrihedron.hxx>
+#include <GeomFill_Fixed.hxx>
+#include <GeomFill_Frenet.hxx>
#include <GeomFill_GuideTrihedronAC.hxx>
#include <GeomFill_GuideTrihedronPlan.hxx>
#include <GeomFill_LocationGuide.hxx>
-
-//Specif Guide
-#include <GeomAdaptor_HCurve.hxx>
-
-#include <gp_Trsf.hxx>
+#include <GeomFill_SectionLaw.hxx>
+#include <GeomFill_TrihedronLaw.hxx>
+#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
+#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
+#include <GProp_GProps.hxx>
+#include <IntCurveSurface_HInter.hxx>
+#include <IntCurveSurface_IntersectionPoint.hxx>
+#include <Law_Function.hxx>
+#include <Law_Interpol.hxx>
#include <Precision.hxx>
-
-#include <Standard_NotImplemented.hxx>
#include <Standard_ConstructionError.hxx>
+#include <Standard_DomainError.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_Type.hxx>
#include <StdFail_NotDone.hxx>
+#include <TColgp_HArray1OfPnt2d.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TopExp.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_SequenceOfShape.hxx>
-#include <BRepBuilderAPI_Copy.hxx>
+#include <stdio.h>
+IMPLEMENT_STANDARD_RTTIEXT(BRepFill_PipeShell,MMgt_TShared)
+//Specification Guide
#ifdef DRAW
#include <Draw.hxx>
#include <DrawTrSurf.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfIntegerShape.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,
//=======================================================================
//function : ComputeSection
-//purpose : Construit une section intermediaire
+//purpose : Construct an intermediary section
//=======================================================================
static Standard_Boolean ComputeSection(const TopoDS_Wire& W1,
BRepFill_CompatibleWires CW(SSh);
CW.SetPercent(0.1);
CW.Perform();
- if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
- Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),SR,0.,1.)
-;
+ if (!CW.IsDone()) throw StdFail_NotDone("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 : Modifie une loi de loc en fonction de Transition
+//purpose : Modify a law of location depending on Transition
//=======================================================================
static void PerformTransition(const BRepFill_TransitionStyle Mode,
}
//=======================================================================
//function : PerformPlan
-//purpose : Construit s'il existe un plan de remplissage
+//purpose : Construct a plane of filling if exists
//=======================================================================
static Standard_Boolean PerformPlan(TopoDS_Shape& S)
//=======================================================================
BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
: mySpine(Spine),
- myTrihedron(GeomFill_IsCorrectedFrenet),
- myTransition(BRepFill_Modified),
- myStatus(GeomFill_PipeOk)
+ myForceApproxC1(Standard_False),
+ myIsAutomaticLaw(Standard_False),
+ myTrihedron(GeomFill_IsCorrectedFrenet),
+ myTransition(BRepFill_Modified),
+ myStatus(GeomFill_PipeOk)
{
myLocation.Nullify();
mySection.Nullify();
myLaw.Nullify();
SetTolerance();
- // Attention aux wire closed non declare !
+ myMaxDegree = 11;
+ myMaxSegments = 100;
+
+ // Attention to closed non-declared wire !
if (!mySpine.Closed()) {
TopoDS_Vertex Vf, Vl;
TopExp::Vertices(mySpine, Vf, Vl);
//=======================================================================
//function : Set
-//purpose : Definie une loi de Frenet (Corrige)
+//purpose : Define a law of Frenet (Correct)
//=======================================================================
void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet)
{
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
- mySection.Nullify(); //Il faut relocaliser les sections.
+ 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 : Definie une loi Constante
+//purpose : Define a law Constant
//=======================================================================
void BRepFill_PipeShell::Set(const gp_Ax2& Axe)
{
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
- mySection.Nullify(); //Il faut relocaliser les sections.
+ mySection.Nullify(); //It is required to relocalize sections.
}
//=======================================================================
//function : Set
-//purpose : Construit une loi de location de type binormal fixe
+//purpose : Construct a law of location of binormal fixed type
//=======================================================================
void BRepFill_PipeShell::Set(const gp_Dir& BiNormal)
{
//=======================================================================
//function : Set
-//purpose : Construit une loi de location de type Darboux
+//purpose : Construct a law of location of Darboux type
//=======================================================================
Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport)
{
Standard_Boolean B;
- // Il faut une loi de location speciale
+ // 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(); //Il faut relocaliser les sections.
+ mySection.Nullify(); //It is required to relocalize the sections.
}
return B;
}
//=======================================================================
//function : Set
-//purpose : Definit une loi a l'aide d'un contour guide
+//purpose : Defines a lawv with help of a guided contour
//=======================================================================
void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
const Standard_Boolean CurvilinearEquivalence,
- const Standard_Boolean KeepContact)
+ const BRepFill_TypeOfContact KeepContact)
{
- // Reorganisation du guide (pb d'orientation et d'origine)
+ // 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) {
- // Cas ouvert reorientation du guide
+ // Case open reorientation of the guide
TopoDS_Wire sp = mySpine;
TopTools_SequenceOfShape Seq;
Seq.Append(sp);
BRepFill_CompatibleWires CW(Seq);
CW.SetPercent(0.1);
CW.Perform();
- if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
+ if (!CW.IsDone()) throw StdFail_NotDone("Uncompatible wires");
TheGuide = TopoDS::Wire(CW.Shape().Value(2));
}
else if (GuideClose) {
- // Cas guide ferme : Determination de l'origine
- // & reorientation du guide
+ // Case guide closed : Determination of the origin
+ // & reorientation of the guide
gp_Vec Dir;
gp_Pnt SpOr;
if (!SpClose) {
if (Affich)
DBRep::Set("theguide", TheGuide);
#endif
- // on transforme le guide en 1 seule courbe (periodic si posssible)
+ // 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) { // triedre par abscisse curviligne reduite
- if (KeepContact)
- myTrihedron = GeomFill_IsGuideACWithContact; // avec rotation
+ if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
+ if (KeepContact == BRepFill_Contact ||
+ KeepContact == BRepFill_ContactOnBorder)
+ myTrihedron = GeomFill_IsGuideACWithContact; // with rotation
else
- myTrihedron = GeomFill_IsGuideAC; // sans rotation
+ myTrihedron = GeomFill_IsGuideAC; // without rotation
Handle(GeomFill_GuideTrihedronAC) TLaw
= new (GeomFill_GuideTrihedronAC) (Guide);
new (GeomFill_LocationGuide) (TLaw);
myLocation = new (BRepFill_ACRLaw) (mySpine, Loc);
}
- else {// triedre par plan
- if (KeepContact)
- myTrihedron = GeomFill_IsGuidePlanWithContact; // avec rotation
+ else {// trihedron by plane
+ if (KeepContact == BRepFill_Contact ||
+ KeepContact == BRepFill_ContactOnBorder)
+ myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation
else
- myTrihedron = GeomFill_IsGuidePlan; // sans rotation
+ myTrihedron = GeomFill_IsGuidePlan; // without rotation
Handle(GeomFill_GuideTrihedronPlan) TLaw =
new (GeomFill_GuideTrihedronPlan) (Guide);
new (GeomFill_LocationGuide) (TLaw);
myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
}
- mySection.Nullify(); //Il faut relocaliser les sections.
+ 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 : Ajoute une Section
+//purpose : Add a Section
//=======================================================================
void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
const Standard_Boolean WithContact,
//=======================================================================
//function : Add
-//purpose : Ajoute une Section
+//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); // Pas de duplication
- BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
- mySeq.Append(S);
- mySection.Nullify();
- ResetLoc();
+ DeleteProfile(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 + Loi d'homothetie
+//purpose : Section + law of homothety
//=======================================================================
void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
const Handle(Law_Function)& L,
//=======================================================================
//function : SetLaw
-//purpose : Section + Loi d'homothetie
+//purpose : Section + Law of homothety
//=======================================================================
void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
const Handle(Law_Function)& L,
//=======================================================================
//function : Delete
-//purpose : Supprime une section
+//purpose : Delete a section
//=======================================================================
- void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile)
+ void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile)
{
Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
//=======================================================================
//function : SetTransition
-//purpose : Definit le mode de traitement des coins
+//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(); //Il faut relocaliser les sections.
+ mySection.Nullify(); //It is required to relocalize the sections.
myTransition = Mode;
angmin = Angmin;
angmax = Angmax;
//=======================================================================
//function : Simulate
-//purpose : Calcul N Sections
+//purpose : Calculate N Sections
//=======================================================================
void BRepFill_PipeShell::Simulate(const Standard_Integer N,
TopTools_ListOfShape& List)
Standard_Boolean Finis=Standard_False;
TopoDS_Shape W;
- // Calcul des parametres de digitalisation
+ // 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); // Init de Last
+ myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last
for (U=0.0, ii=1; !Finis ; U+=Delta) {
if (U >= Length) {
U = Length;
}
else {
if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last);
- if (U > Last) U = (Last+First)/2; // On ne saute pas une arete
+ if (U > Last) U = (Last+First)/2; // The edge is not skipped
if (U> First) ii++;
}
US = FirstS + (U/Length)*DeltaS;
//=======================================================================
//function : Build
-//purpose : Construit le Shell et l'historique
+//purpose : Construct the Shell and the history
//=======================================================================
Standard_Boolean BRepFill_PipeShell::Build()
{
return Standard_False;
}
- // 2) Calcul de myFirst et myLast
+ // 2) Calculate myFirst and myLast
mySection->Law(1)->GetDomain(FirstS, LastS);
mySection->D0(FirstS, myFirst);
myLocation->D0(0, myFirst);
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));
- MkSw.Build(myTransition);
+ 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;
Standard_Boolean BRepFill_PipeShell::MakeSolid()
{
if (myShape.IsNull())
- StdFail_NotDone::Raise("PipeShell is not build");
+ throw StdFail_NotDone("PipeShell is not built");
Standard_Boolean B = myShape.Closed();
BRep_Builder BS;
B = (myFirst.Closed() && myLast.Closed());
}
if (B) {
- // Il faut boucher les extremites
+ // It is necessary to block the extremities
B = PerformPlan(myFirst);
if (B) {
B = PerformPlan(myLast);
//=======================================================================
//function : Shape
-//purpose : Renvoi le resultat
+//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 : Renvoi la section du debut
+//purpose : Return the start section
//=======================================================================
const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const
{
//=======================================================================
//function : LastShape
-//purpose : Renvoi la section de fin
+//purpose : Return the end section
//=======================================================================
const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
{
void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape,
TopTools_ListOfShape& theList)
{
- // Standard_NotImplemented::Raise("Generated:Pas Fait");
+ // throw Standard_NotImplemented("Generated:Pas Fait");
+
theList.Clear();
if(myGenMap.IsBound(theShape)) {
theList = myGenMap.Find(theShape);
- }
+ }
}
//=======================================================================
//function : Prepare
-//purpose : - Verifie que tout est pret
-// - Construit la loi de section
-// - Construit la loi de location si necessaire
-// - Calcul First & Last
+//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()
{
+ WSeq.Clear();
+ myEdgeNewEdges.Clear();
+
TopoDS_Wire theSect;
- if (!IsReady()) StdFail_NotDone::Raise("PipeShell");
- if (!myLocation.IsNull() && !mySection.IsNull()) return; // C'est deja pret
+ if (!IsReady()) throw StdFail_NotDone("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;;
+ TopoDS_Iterator iter;
for (i = 2; i <= mySeq.Length()-1; i++)
{
Standard_Boolean wdeg = Standard_True;
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
- Standard_Failure::Raise("Wrong usage of punctual sections");
+ throw Standard_Failure("Wrong usage of punctual sections");
}
if (mySeq.Length() <= 2)
{
wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
}
if (wdeg)
- Standard_Failure::Raise("Wrong usage of punctual sections");
+ throw Standard_Failure("Wrong usage of punctual sections");
}
- // Construction de la loi de location
+ // Construction of the law of location
if(myLocation.IsNull())
{
switch(myTrihedron)
break;
}
default :
- { // Pas prevu !
- Standard_ConstructionError::Raise("PipeShell");
+ { // Not planned!
+ throw Standard_ConstructionError("PipeShell");
}
}
}
- //Transformation de la loi (Gestion Transition)
+ //Transformation of the law (Transition Management)
PerformTransition(myTransition, myLocation, angmin);
- // Construction de la loi de section
+ // Construction of the section law
if (mySeq.Length() == 1) {
Standard_Real p1;
- Place(mySeq(1), theSect,p1);
+ gp_Trsf aTrsf;
+ Place(mySeq(1), theSect, aTrsf, p1);
TopoDS_Wire aLocalShape = theSect;
if (mySeq(1).IsLaw())
mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw);
else
mySection = new BRepFill_ShapeLaw(aLocalShape);
// mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect));
- }
- else
+
+ WSeq.Append(theSect);
+ //Simple case of single section
+ myIndOfSec.Append(1);
+ TopoDS_Iterator itw(theSect);
+ for (; itw.More(); itw.Next())
{
- TColStd_SequenceOfReal Param;
- TopTools_SequenceOfShape WSeq;
- WSeq.Clear();
- Param.Clear();
- Standard_Integer NbL = myLocation->NbLaw();
- 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, param);
- Param.Append(param);
- WSeq.Append(theSect);
-// WSeq.Append(TopoDS::Wire(theSect));
- if (param==V1) ideb = iseq;
- if (param==V2) ifin = iseq;
+ const TopoDS_Shape& anEdge = itw.Value();
+ TopTools_ListOfShape Elist;
+ Elist.Append(anEdge);
+ myEdgeNewEdges.Bind(anEdge, Elist);
+ }
+ ///////////////////////////////
+ }
+ else
+ {
+ TColStd_SequenceOfReal Param;
+ TColStd_SequenceOfInteger IndSec;
+ GeomFill_SequenceOfTrsf Transformations;
+ 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;
+ Standard_Integer iseq;
+ for (iseq = 1; iseq <= mySeq.Length(); iseq++) {
+ IndSec.Append(iseq);
+ Place(mySeq(iseq), theSect, aTrsf, param);
+ Param.Append(param);
+ WSeq.Append(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));
}
-
-
- // sections bouclantes ?
- if (myLocation->IsClosed()) {
- if (ideb>0) {
- // on place la section initiale en position finale
- 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 = RealLast(), pmax = RealFirst();
+ TopoDS_Wire Wmin, Wmax;
+ for (iseq = 1; 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));
+ }
}
- else if (ifin>0) {
- // on place la section finale en position initiale
+ // 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(WSeq(ifin));
+ WSeq.Append(Wres);
+ IndSec.Append(WSeq.Length());
+ Param.Append(V2);
+ WSeq.Append(Wres);
+ IndSec.Append(WSeq.Length());
}
- else {
- // il faut trouver une section moyenne a imposer en V1 et en 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));
- }
- }
- // section moyenne entre Wmin et Wmax
- TopoDS_Wire Wres;
- Standard_Real dmin = Abs(pmin-V1);
- Standard_Real dmax = Abs(pmax-V2);
- if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) {
- // on impose la section Wres au debut et a la fin
- 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);
+ IndSec.Exchange(iseq,jseq);
+ play_again = Standard_True;
}
-
}
}
-
- // tri des sections par parametre croissant
- 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;
- }
- }
- }
- }
-
+ }
+ //Fill the array of real indices of sections
+ for (Standard_Integer ii = 1; ii <= mySeq.Length(); ii++)
+ for (Standard_Integer jj = 1; jj <= IndSec.Length(); jj++)
+ if (IndSec(jj) == ii)
+ {
+ myIndOfSec.Append(jj);
+ break;
+ }
+
#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)));
+ 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
-
-
-
- // Calcul des sections de travail
- 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");
+
+
+
+ // Calculate work sections
+ TopTools_SequenceOfShape WorkingSections;
+ WorkingSections.Clear();
+ TopTools_DataMapOfShapeListOfShape WorkingMap;
+ BRepFill_CompatibleWires Georges(WSeq);
+ Georges.SetPercent(0.1);
+ Georges.Perform(Standard_False);
+ if (Georges.IsDone()) {
+ WorkingSections = Georges.Shape();
+ WorkingMap = Georges.Generated();
+ //For each sub-edge of each section
+ //we save its splits
+ for (Standard_Integer ii = 1; ii <= WSeq.Length(); ii++)
+ {
+ TopExp_Explorer Explo(WSeq(ii), TopAbs_EDGE);
+ for (; Explo.More(); Explo.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+ TopTools_ListOfShape aNewEdges = Georges.GeneratedShapes(anEdge);
+ myEdgeNewEdges.Bind(anEdge, aNewEdges);
+ }
}
- mySection = new (BRepFill_NSections) (WorkingSections,Param,V1,V2);
-
- }// else
+ }
+ else {
+ throw Standard_ConstructionError("PipeShell : uncompatible wires");
+ }
+ mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2);
+
+ }// else
- // on modifie la loi de location si contact
+ // modify the law of location if contact
if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
|| (myTrihedron == GeomFill_IsGuideACWithContact) ) {
Standard_Real fs, f, l, Delta, Length;
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); // on force la rotation
+ old_angle, angle); // force the rotation
old_angle = angle;
}
}
myStatus = myLocation->GetStatus();
+ if (!mySection->IsDone())
+ myStatus = GeomFill_PipeNotOk;
}
//=======================================================================
//function : Place
-//purpose : Met en Place une Section dans le repere local
-// et retourne son parametre sur la trajectoire
+//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.Vertex(),
Sec.WithContact(),
Sec.WithCorrection());
- W = Sec.Wire();
- TopLoc_Location Loc2(Place.Transformation()), Loc1;
- Loc1 = W.Location();
- W.Location(Loc2.Multiplied(Loc1));
+ 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 : Supprime les references aux sections dans les loi de location
+//purpose : Remove references to the sections in the laws of location
//=======================================================================
void BRepFill_PipeShell::ResetLoc()
{
Handle(GeomFill_LocationGuide) Loc;
for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) {
Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec));
- Loc->EraseRotation();// on supprime la rotation
+ 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
+//purpose : Builds history for edges and vertices
+// of sections
//=======================================================================
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--) {
- Standard_Boolean ismodified = Standard_False;
- 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);
- }
- }
- }
+ //Filling of <myGenMap>
+ const Handle(TopTools_HArray2OfShape)& anUEdges = theSweep.InterFaces();
+ BRep_Builder BB;
+
+ TopTools_DataMapOfIntegerShape IndWireMap;
+
+ Standard_Integer indw, inde;
+ TopoDS_Iterator itw;
+ for (indw = 1; indw <= mySeq.Length(); indw++)
+ {
+ const TopoDS_Wire& aSection = mySeq(indw).Wire();
+ Standard_Boolean IsPunctual = mySeq(indw).IsPunctual();
+ if (IsPunctual)
+ {
+ //for punctual sections (first or last)
+ //we take all the wires generated along the path
+ TopExp_Explorer Explo(aSection, TopAbs_VERTEX);
+ const TopoDS_Shape& VerSection = Explo.Current();
+ TopTools_ListOfShape Elist;
+ for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++)
+ for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++)
+ Elist.Append(anUEdges->Value(i,j));
+ myGenMap.Bind(VerSection, Elist);
+ continue;
}
- 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);
- }
+ //Take the real index of section on the path
+ Standard_Integer IndOfW = myIndOfSec(indw);
+ const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW));
+ BRepTools_WireExplorer wexp_sec(aSection);
+ for (inde = 1; wexp_sec.More(); wexp_sec.Next())
+ {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
+ if (BRep_Tool::Degenerated(anEdge))
+ continue;
+
+ TopoDS_Shell aShell;
+ BB.MakeShell(aShell);
+ TopoDS_Vertex aVertex [2];
+ TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
+ Standard_Integer SignOfAnEdge =
+ (anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
+
+ //For each non-degenerated inde-th edge of <aSection>
+ //we find inde-th edge in <theWire>
+ TopoDS_Edge theEdge;
+ BRepTools_WireExplorer wexp(theWire);
+ for (Standard_Integer i = 1; wexp.More(); wexp.Next())
+ {
+ theEdge = TopoDS::Edge(wexp.Current());
+ if (BRep_Tool::Degenerated(anEdge))
+ continue;
+ if (i == inde)
+ break;
+ i++;
}
- }
-
- 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());
+ //Take the list of splits for <theEdge>
+ const TopTools_ListOfShape& NewEdges = myEdgeNewEdges(theEdge);
+ Standard_Integer SignOfANewEdge = 0, SignOfIndex = 0;
+ TopTools_ListIteratorOfListOfShape iter(NewEdges);
+ for (; iter.More(); iter.Next())
+ {
+ const TopoDS_Edge& aNewEdge = TopoDS::Edge(iter.Value());
+ SignOfANewEdge = (aNewEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
+ Standard_Integer anIndE = mySection->IndexOfEdge(aNewEdge);
+ SignOfIndex = (anIndE > 0)? 1 : -1;
+ anIndE = Abs(anIndE);
+ //For an edge generated shape is a "tape" -
+ //a shell usually containing this edge and
+ //passing from beginning of path to its end
+ TopoDS_Shape aTape = theSweep.Tape(anIndE);
+ TopoDS_Iterator itsh(aTape);
+ for (; itsh.More(); itsh.Next())
+ BB.Add(aShell, itsh.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);
- }
- }
- }
+ //Processing of vertices of <anEdge>
+ //We should choose right index in <anUEdges>
+ //for each vertex of edge
+ Standard_Integer ToReverse = SignOfAnEdge * SignOfANewEdge * SignOfIndex;
+ Standard_Integer UIndex [2];
+ UIndex[0] = Abs(mySection->IndexOfEdge(NewEdges.First()));
+ UIndex[1] = Abs(mySection->IndexOfEdge(NewEdges.Last())) + ToReverse;
+ if (ToReverse == -1)
+ {
+ UIndex[0]++;
+ UIndex[1]++;
}
- // 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;
- 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, param);
-
- if(param < aparmin) {
- ideb = iseq;
- aparmin = param;
+ if (mySection->IsUClosed())
+ {
+ if (UIndex[0] > mySection->NbLaw())
+ UIndex[0] = 1;
+ if (UIndex[1] > mySection->NbLaw())
+ UIndex[1] = 1;
}
+ //if (SignOfAnEdge * SignOfANewEdge == -1)
+ if (SignOfAnEdge == -1 ||
+ SignOfANewEdge == -1)
+ { Standard_Integer Tmp = UIndex[0]; UIndex[0] = UIndex[1]; UIndex[1] = Tmp; }
+
+ TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+ TopExp::MapShapesAndAncestors(aShell, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
+ for (Standard_Integer kk = 0; kk < 2; kk++)
+ {
+ if (myGenMap.IsBound(aVertex[kk]))
+ continue;
+ if (IndWireMap.IsBound(UIndex[kk]))
+ {
+ TopTools_ListOfShape Wlist;
+ Wlist.Append(IndWireMap(UIndex[kk]));
+ myGenMap.Bind(aVertex[kk], Wlist);
+ continue;
+ }
+
+ //Collect u-edges
+ TopTools_SequenceOfShape SeqEdges;
+ Standard_Integer jj;
+ for (jj = 1; jj <= anUEdges->UpperCol(); jj++)
+ SeqEdges.Append(anUEdges->Value(UIndex[kk], jj));
+
+ //Assemble the wire ("rail" along the path)
+ //checking for possible holes
+ //(they appear with option "Round Corner")
+ //and filling them
+ //Missed edges are taken from <aShell>
+ TopoDS_Wire aWire;
+ BB.MakeWire(aWire);
+ const TopoDS_Edge& FirstEdge = TopoDS::Edge(SeqEdges(1));
+ if (FirstEdge.IsNull())
+ continue;
+ BB.Add(aWire, FirstEdge);
+ TopoDS_Vertex FirstVertex, CurVertex;
+ TopExp::Vertices(FirstEdge, FirstVertex, CurVertex);
+ TopoDS_Edge CurEdge;
+ for (jj = 2; jj <= SeqEdges.Length(); jj++)
+ {
+ CurEdge = TopoDS::Edge(SeqEdges(jj));
+ TopoDS_Vertex Vfirst, Vlast;
+ TopExp::Vertices(CurEdge, Vfirst, Vlast);
+ if (CurVertex.IsSame(Vfirst))
+ CurVertex = Vlast;
+ else //a hole
+ {
+ const TopTools_ListOfShape& Elist = VEmap.FindFromKey(Vfirst);
+ TopTools_ListIteratorOfListOfShape itl(Elist);
+ for (; itl.More(); itl.Next())
+ {
+ const TopoDS_Edge& Candidate = TopoDS::Edge(itl.Value());
+ if (Candidate.IsSame(CurEdge))
+ continue;
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(Candidate, V1, V2);
+ if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
+ {
+ BB.Add(aWire, Candidate);
+ break;
+ }
+ }
+ }
+ CurVertex = Vlast;
+ BB.Add(aWire, CurEdge);
+ } //for (jj = 2; jj <= SeqEdges.Length(); jj++)
+ //case of closed wire
+ if (mySection->IsVClosed() &&
+ !CurVertex.IsSame(FirstVertex))
+ {
+ const TopTools_ListOfShape& Elist = VEmap.FindFromKey(CurVertex);
+ TopTools_ListIteratorOfListOfShape itl(Elist);
+ for (; itl.More(); itl.Next())
+ {
+ const TopoDS_Edge& Candidate = TopoDS::Edge(itl.Value());
+ if (Candidate.IsSame(CurEdge))
+ continue;
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(Candidate, V1, V2);
+ if (V1.IsSame(FirstVertex) || V2.IsSame(FirstVertex))
+ {
+ BB.Add(aWire, Candidate);
+ break;
+ }
+ }
+ }
+ TopTools_ListOfShape Wlist;
+ Wlist.Append(aWire);
+ myGenMap.Bind(aVertex[kk], Wlist);
+ //Save already built wire with its index
+ IndWireMap.Bind(UIndex[kk], aWire);
+ } //for (Standard_Integer kk = 0; kk < 2; kk++)
+ ////////////////////////////////////
+
+ TopTools_ListOfShape ListShell;
+ ListShell.Append(aShell);
+ myGenMap.Bind(anEdge, ListShell);
+ ////////////////////////
- if(param > aparmax) {
- ifin = iseq;
- aparmax = param;
- }
+ inde++;
}
-
- 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