Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1996-03-07
// Created by: Jean Yves LEBEY
// Copyright (c) 1996-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 <BRep_Tool.hxx>
#include <BRepClass3d_SolidExplorer.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopOpeBRepBuild_define.hxx>
#include <TopOpeBRepBuild_FaceBuilder.hxx>
#include <TopOpeBRepBuild_FuseFace.hxx>
#include <TopOpeBRepBuild_GTopo.hxx>
#include <TopOpeBRepBuild_ShapeSet.hxx>
#include <TopOpeBRepBuild_ShellFaceSet.hxx>
#include <TopOpeBRepDS_EXPORT.hxx>
#include <TopOpeBRepDS_HDataStructure.hxx>
#include <TopOpeBRepTool_GEOMETRY.hxx>
#include <TopOpeBRepTool_PROJECT.hxx>
#include <TopOpeBRepTool_TOPOLOGY.hxx>
#include <TopOpeBRepTool_SC.hxx>
#ifdef OCCT_DEBUG
#define DEBSHASET(sarg, meth, shaset, str) \
TCollection_AsciiString sarg((meth)); \
(sarg) = (sarg) + (shaset).DEBNumber() + (str);
Standard_EXPORT void debffsfs(const int i)
{
std::cout << "+++ debffsfs " << i << std::endl;
}
Standard_EXPORT void debffflo(const int i)
{
std::cout << "+++ debffflo " << i << std::endl;
}
#endif
static thread_local bool STATIC_motheropedef = false;
static thread_local TopOpeBRepBuild_GTopo STATIC_Gmotherope;
Standard_EXPORT void FUN_setmotherope(const TopOpeBRepBuild_GTopo& G)
{
STATIC_Gmotherope = G;
STATIC_motheropedef = true;
}
Standard_EXPORT void FUN_unsetmotherope()
{
STATIC_motheropedef = false;
}
Standard_EXPORT bool FUN_ismotheropedef()
{
return STATIC_motheropedef;
}
Standard_EXPORT const TopOpeBRepBuild_GTopo& FUN_motherope()
{
return STATIC_Gmotherope;
}
// Standard_IMPORT extern bool GLOBAL_classifysplitedge;
Standard_EXPORTEXTERN bool GLOBAL_classifysplitedge;
// Standard_IMPORT extern bool GLOBAL_revownsplfacori;
Standard_EXPORTEXTERN bool GLOBAL_revownsplfacori;
Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B,
const NCollection_List<TopoDS_Shape>& LF1,
const NCollection_List<TopoDS_Shape>& LF2,
const TopOpeBRepDS_Config c1,
const TopOpeBRepDS_Config c2);
Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& B,
const TopoDS_Shape& f,
bool& of1,
bool& of2);
static int FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,
TopOpeBRepTool_ShapeClassifier& SC,
const NCollection_List<TopoDS_Shape>& LF,
const TopoDS_Shape& fsp,
bool& p3ddef,
gp_Pnt& p3d);
static int FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,
TopOpeBRepTool_ShapeClassifier& SC,
const NCollection_List<TopoDS_Shape>& LF1,
const NCollection_List<TopoDS_Shape>& LF2,
const TopoDS_Shape& fsp);
#ifdef OCCT_DEBUG
// static void FUN_getAncestorFsp(const occ::handle<TopOpeBRepDS_HDataStructure>&
// HDS,TopOpeBRepTool_ShapeClassifier& SC,const NCollection_List<TopoDS_Shape>& LF1,const
// NCollection_List<TopoDS_Shape>& LF2,const NCollection_List<TopoDS_Shape>& spFOR,
// NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>*
// SplitAnc);
#endif
static int FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,
TopOpeBRepTool_ShapeClassifier& SC,
const NCollection_List<TopoDS_Shape>& LF,
const TopoDS_Shape& fsp,
bool& p3ddef,
gp_Pnt& p3d)
{
const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS(); // How to do static <--> const
NCollection_List<TopoDS_Shape>::Iterator itf(LF);
for (; itf.More(); itf.Next())
{
const TopoDS_Face& f = TopoDS::Face(itf.Value());
TopAbs_State st = SC.StateShapeShape(fsp, f, 1);
if ((st == TopAbs_UNKNOWN) || (st == TopAbs_OUT))
{
continue;
}
if (st == TopAbs_ON)
{
if (!p3ddef)
{
bool ok = BRepClass3d_SolidExplorer::FindAPointInTheFace(TopoDS::Face(fsp), p3d);
if (!ok)
{
return 0;
}
p3ddef = true;
}
gp_Pnt2d p2d;
double dd = 0.;
bool ok = FUN_tool_projPonF(p3d, f, p2d, dd);
if (!ok)
{
return 0;
}
double tolf = BRep_Tool::Tolerance(f) * 1.e1;
if (dd > tolf)
{
return 0;
}
double TolClass = 1e-8;
BRepTopAdaptor_FClass2d FClass2d(f, TolClass);
st = FClass2d.Perform(p2d);
}
if (st == TopAbs_IN)
{
int ianc = BDS.Shape(f);
return ianc;
}
} // itf(LF)
return 0;
}
static int FUN_getAncestorFsp(TopOpeBRepBuild_Builder& B,
TopOpeBRepTool_ShapeClassifier& SC,
const NCollection_List<TopoDS_Shape>& LF1,
const NCollection_List<TopoDS_Shape>& LF2,
const TopoDS_Shape& fsp)
{
// IMPORTANT : fsp is split IN/OUT of F1,so it has only one ancestor face
// LF1 faces sdm with LF2
const TopOpeBRepDS_DataStructure& BDS = B.DataStructure()->DS();
bool of1, of2;
FUNBUILD_ANCESTORRANKGET(B, fsp, of1, of2);
int rkfsp = 0;
if (of1 && !of2)
{
rkfsp = 1;
}
else if (of2 && !of1)
{
rkfsp = 2;
}
bool unk = (rkfsp == 0);
int rkf1 = BDS.AncestorRank(LF1.First());
int rkf2 = BDS.AncestorRank(LF2.First());
bool p3ddef = false;
gp_Pnt p3d;
bool ison1 = (rkf1 == rkfsp);
bool ison2 = (rkf2 == rkfsp);
int ianc1 = 0, ianc2 = 0;
if (ison1 || unk)
{
ianc1 = FUN_getAncestorFsp(B, SC, LF1, fsp, p3ddef, p3d);
}
if (ison1)
{
return ianc1;
}
if (ison2 || unk)
{
ianc2 = FUN_getAncestorFsp(B, SC, LF2, fsp, p3ddef, p3d);
}
if (ison2)
{
return ianc2;
}
if (ianc1 + ianc2 > 0)
{
if (ianc1 == 0)
{
return ianc2;
}
else if (ianc2 == 0)
{
return ianc1;
}
else
{
return 0; // fsp has 2 ancestor faces
}
}
return 0;
}
Standard_EXPORT NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>* GLOBAL_SplitAnc =
nullptr; // xpu260598
static void FUN_getAncestorFsp(
TopOpeBRepBuild_Builder& B,
TopOpeBRepTool_ShapeClassifier& SC,
const NCollection_List<TopoDS_Shape>& LF1,
const NCollection_List<TopoDS_Shape>& LF2,
const TopoDS_Shape& FOR,
NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>* SplitAnc)
{
if (SplitAnc == nullptr)
{
return;
}
bool issplitIN = B.IsSplit(FOR, TopAbs_IN);
bool issplitOU = B.IsSplit(FOR, TopAbs_OUT);
if (!issplitIN && !issplitOU)
{
return;
}
NCollection_List<TopoDS_Shape> spFOR;
if (issplitIN)
{
FDS_copy(B.Splits(FOR, TopAbs_IN), spFOR);
}
if (issplitOU)
{
FDS_copy(B.Splits(FOR, TopAbs_OUT), spFOR);
}
for (NCollection_List<TopoDS_Shape>::Iterator itsp(spFOR); itsp.More(); itsp.Next())
{
const TopoDS_Shape& fsp = itsp.Value();
bool isbound = SplitAnc->IsBound(fsp);
if (isbound)
{
continue;
}
int ianc = FUN_getAncestorFsp(B, SC, LF1, LF2, fsp);
if (ianc != 0)
{
SplitAnc->Bind(fsp, ianc);
}
} // itsp
}
Standard_EXPORT NCollection_List<TopoDS_Shape>* GLOBAL_lfr1 = nullptr;
Standard_EXPORT bool GLOBAL_lfrtoprocess = false;
// Standard_IMPORT extern NCollection_List<TopoDS_Shape>* GLOBAL_lfr1;
// Standard_IMPORT NCollection_List<TopoDS_Shape>* GLOBAL_lfr1;
// Standard_IMPORT extern bool GLOBAL_lfrtoprocess;
// Standard_IMPORT bool GLOBAL_lfrtoprocess;
//=================================================================================================
void TopOpeBRepBuild_Builder::GFillFaceSFS(const TopoDS_Shape& FOR,
const NCollection_List<TopoDS_Shape>& LSO2,
const TopOpeBRepBuild_GTopo& Gin,
TopOpeBRepBuild_ShellFaceSet& SFS)
{
TopAbs_State TB1, TB2;
Gin.StatesON(TB1, TB2);
#ifdef OCCT_DEBUG
int iF;
bool tSPS = GtraceSPS(FOR, iF);
if (tSPS)
std::cout << std::endl;
#endif
const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
bool tosplit = GToSplit(FOR, TB1);
bool tomerge = GToMerge(FOR);
#ifdef OCCT_DEBUG
// int iFOR = BDS.Shape(FOR);
#endif
int rkFOR = BDS.AncestorRank(FOR);
#ifdef OCCT_DEBUG
if (tSPS)
{
GdumpSHASTA(FOR, TB1, "--- GFillFaceSFS START ");
std::cout << " tosplit " << tosplit << " tomerge " << tomerge << std::endl;
debffsfs(iF);
}
#endif
TopoDS_Shape FF = FOR;
FF.Orientation(TopAbs_FORWARD);
bool hsd = myDataStructure->HasSameDomain(FOR); // xpu280598
GLOBAL_lfrtoprocess = false;
if (tosplit && tomerge)
{
// merge des faces SameDomain
// on effectue le merge ssi FOR est la reference de ses faces SameDomain
int iref = myDataStructure->SameDomainReference(FOR);
const TopoDS_Shape& fref = myDataStructure->Shape(iref);
bool isref = FOR.IsSame(fref);
bool makemerge = isref;
// xpu280199 PRO16958 : f10=ref(f6), GToMerge(f10)=false
bool makemergeref = GToMerge(fref);
makemerge = makemerge || (!makemergeref && (rkFOR == 1));
if (makemerge)
{
#ifdef OCCT_DEBUG
if (tSPS)
{
GdumpSHASTA(FOR, TB1, "[[[[[[[[[[[[[[[[[[[[[[[[[[ GFillFaceSFS makemerge START ");
std::cout << std::endl;
}
#endif
bool performfufa = true;
if (performfufa)
{
GLOBAL_lfrtoprocess = true;
if (GLOBAL_lfrtoprocess)
{
if (GLOBAL_lfr1 == nullptr)
{
GLOBAL_lfr1 = (NCollection_List<TopoDS_Shape>*)new NCollection_List<TopoDS_Shape>();
}
GLOBAL_lfr1->Clear();
}
}
// xpu280598 : Filling up GLOBAL_SplitAnc = {(fsp,ifanc)}
// . fsp = spIN/OU(fanc),
// . fanc hsdm is the unique ancestor face
if (GLOBAL_SplitAnc == nullptr)
{
GLOBAL_SplitAnc =
(NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>*)new NCollection_DataMap<
TopoDS_Shape,
int,
TopTools_ShapeMapHasher>();
}
GLOBAL_SplitAnc->Clear();
NCollection_List<TopoDS_Shape> LFSO, LFDO, LFSO1, LFDO1, LFSO2, LFDO2;
GFindSamDomSODO(FF, LFSO, LFDO); // -980617
// FDSSDM_sordor(FF,LFSO,LFDO);
int rankF = GShapeRank(FF), rankX = (rankF) ? ((rankF == 1) ? 2 : 1) : 0;
GFindSameRank(LFSO, rankF, LFSO1);
GFindSameRank(LFDO, rankF, LFDO1);
GFindSameRank(LFSO, rankX, LFSO2);
GFindSameRank(LFDO, rankX, LFDO2);
NCollection_List<TopoDS_Shape> LF1, LF2;
TopOpeBRepBuild_GTopo GM;
TopAbs_State TB, NTB;
bool dodo;
int l1, l2;
// WES : toutes les faces de meme orientation topologique
LF1 = LFSO1; // NYI pointeurs
LF2 = LFSO2; // NYI pointeurs
l1 = LF1.Extent();
l2 = LF2.Extent();
dodo = (l1 != 0) && (l2 != 0);
FUN_unsetmotherope(); // +12/07
GM = Gin;
GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED, TopOpeBRepDS_SAMEORIENTED);
if (dodo)
{
#ifdef OCCT_DEBUG
if (tSPS)
{
GdumpSAMDOM(LF1, (char*)"LF1 (LFSO1) : ");
GdumpSAMDOM(LF2, (char*)"LF2 (LFSO2) : ");
}
#endif
GLOBAL_classifysplitedge = true;
GFillFacesWESMakeFaces(LF1, LF2, LSO2, GM);
GLOBAL_classifysplitedge = false;
GLOBAL_revownsplfacori = true;
FUNBUILD_ANCESTORRANKPREPARE(*this,
LF1,
LF2,
TopOpeBRepDS_SAMEORIENTED,
TopOpeBRepDS_SAMEORIENTED);
if (hsd)
{
FUN_getAncestorFsp((*this),
myShapeClassifier,
LF1,
LF2,
FOR,
GLOBAL_SplitAnc); // xpu280598
}
// GLOBAL_lfrtoprocess = t
// ==> on ne stocke PAS les faces 'startelement' dans le SFS
// mais dans GLOBAL_lfr1,
// GLOBAL_lfrtoprocess = f
// ==> on stocke normalement dans le SFS et pas dans GLOBAL_lfr1
// NYI : + argument a la methode GSplitFaceSFS ?? a voir
// ici : GLOBAL_lfrtoprocess = t
// clang-format off
if (GLOBAL_lfr1==nullptr) { GLOBAL_lfr1=(NCollection_List<TopoDS_Shape>*)new NCollection_List<TopoDS_Shape>(); //flo150998
}
// clang-format on
GLOBAL_lfr1->Clear();
GSplitFaceSFS(FOR, LSO2, GM, SFS);
GLOBAL_lfrtoprocess = false;
GLOBAL_revownsplfacori = false;
}
// WES : FOR + faces d'orientation topologique opposee
LF1 = LFSO1; // NYI pointeurs
LF2 = LFDO2; // NYI pointeurs
l1 = LF1.Extent();
l2 = LF2.Extent();
dodo = (l1 != 0) && (l2 != 0);
GM = Gin; // OUT,OUT-> OUT,IN + IN OUT
TB = TB2; // ------
NTB = TopAbs_IN; // NTB = (TB == TopAbs_OUT) ? TopAbs_IN : TopAbs_OUT;
GM.ChangeValue(TB, TopAbs_ON, false);
GM.ChangeValue(NTB, TopAbs_ON, true);
GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED, TopOpeBRepDS_DIFFORIENTED);
FUN_setmotherope(GM); // +12/07
if (dodo)
{
#ifdef OCCT_DEBUG
if (tSPS)
{
TopAbs_State TB11, TB21;
GM.StatesON(TB11, TB21);
std::cout << std::endl;
std::cout << "@@@@" << std::endl;
std::cout << "@@@@@@@@ partie 1 : ";
TopAbs::Print(TB11, std::cout);
std::cout << " ";
TopAbs::Print(TB21, std::cout);
std::cout << std::endl;
std::cout << "@@@@" << std::endl;
GdumpSAMDOM(LF1, (char*)"LF1 (LFSO1) : ");
GdumpSAMDOM(LF2, (char*)"LF2 (LFDO2) : ");
std::cout << std::endl;
}
#endif
GLOBAL_classifysplitedge = true;
GFillFacesWESMakeFaces(LF1, LF2, LSO2, GM);
GLOBAL_classifysplitedge = false;
GLOBAL_revownsplfacori = true;
FUNBUILD_ANCESTORRANKPREPARE(*this,
LF1,
LF2,
TopOpeBRepDS_SAMEORIENTED,
TopOpeBRepDS_DIFFORIENTED);
if (hsd)
{
FUN_getAncestorFsp((*this),
myShapeClassifier,
LF1,
LF2,
FOR,
GLOBAL_SplitAnc); // xpu280598
}
if (Opecom())
{
bool issplitIN = IsSplit(FOR, TopAbs_IN);
if (issplitIN)
{
const NCollection_List<TopoDS_Shape>& spFOR = Splits(FOR, TopAbs_IN);
NCollection_List<TopoDS_Shape> spFORcopy;
FDS_copy(spFOR, spFORcopy);
NCollection_List<TopoDS_Shape>::Iterator it(LF1);
for (; it.More(); it.Next())
{
const TopoDS_Shape& f = it.Value();
bool issplit = IsSplit(f, TopAbs_IN);
if (issplit)
{
ChangeSplit(f, TopAbs_IN).Clear();
}
}
it.Initialize(LF2);
for (; it.More(); it.Next())
{
const TopoDS_Shape& f = it.Value();
bool issplit = IsSplit(f, TopAbs_IN);
if (issplit)
{
ChangeSplit(f, TopAbs_IN).Clear();
}
}
ChangeSplit(FOR, TopAbs_IN).Append(spFORcopy); // keep split for reference
} // issplitIN
} // OpeCom
GSplitFaceSFS(FOR, LSO2, GM, SFS);
GLOBAL_revownsplfacori = false;
} // dodo
if (!Opecom())
{
GM = Gin; // OUT,OUT-> OUT,IN + IN OUT
TB = TB1; // ------
// NTB = (TB == TopAbs_OUT) ? TopAbs_IN : TopAbs_OUT;
NTB = TopAbs_IN;
GM.ChangeValue(TopAbs_ON, TB, false);
GM.ChangeValue(TopAbs_ON, NTB, true);
GM.ChangeConfig(TopOpeBRepDS_SAMEORIENTED, TopOpeBRepDS_DIFFORIENTED);
FUN_setmotherope(GM); // +12/07
if (dodo)
{
#ifdef OCCT_DEBUG
if (tSPS)
{
TopAbs_State TB12, TB22;
GM.StatesON(TB12, TB22);
std::cout << std::endl;
std::cout << "@@@@" << std::endl;
std::cout << "@@@@@@@@ partie 2 : ";
TopAbs::Print(TB12, std::cout);
std::cout << " ";
TopAbs::Print(TB22, std::cout);
std::cout << std::endl;
std::cout << "@@@@" << std::endl;
GdumpSAMDOM(LF1, (char*)"LF1 (LFSO1) : ");
GdumpSAMDOM(LF2, (char*)"LF2 (LFDO2) : ");
std::cout << std::endl;
}
#endif
GLOBAL_classifysplitedge = true;
GFillFacesWESMakeFaces(LF1, LF2, LSO2, GM);
GLOBAL_classifysplitedge = false;
GLOBAL_revownsplfacori = true;
FUNBUILD_ANCESTORRANKPREPARE(*this,
LF1,
LF2,
TopOpeBRepDS_SAMEORIENTED,
TopOpeBRepDS_DIFFORIENTED);
if (hsd)
{
FUN_getAncestorFsp((*this),
myShapeClassifier,
LF1,
LF2,
FOR,
GLOBAL_SplitAnc); // xpu280598
}
GSplitFaceSFS(FOR, LSO2, GM, SFS);
GLOBAL_revownsplfacori = false;
}
} // !Opecom
FUN_unsetmotherope(); // +12/07
#ifdef OCCT_DEBUG
if (tSPS)
{
GdumpSHASTA(FOR, TB1, "]]]]]]]]]]]]]]]]]]]]]]]]]] GFillFaceSFS makemerge END ");
std::cout << std::endl;
}
#endif
GLOBAL_SplitAnc->Clear(); // xpu280598
// FuseFace
SFS.ChangeStartShapes().Extent();
if (performfufa)
{
#ifdef OCCT_DEBUG
if (tSPS)
debffflo(iF);
#endif
// const NCollection_List<TopoDS_Shape>& lou = Splits(FF,TopAbs_OUT); int nou = lou.Extent();
// const NCollection_List<TopoDS_Shape>& lin = Splits(FF,TopAbs_IN); int nin = lin.Extent();
// GCopyList(lou,*GLOBAL_lfr1);
// GCopyList(lin,*GLOBAL_lfr1);
#ifdef OCCT_DEBUG
// int nlfr1 = GLOBAL_lfr1->Extent();
#endif
// NYI : Builder += methode pour le process fufa
// clang-format off
TopOpeBRepBuild_FuseFace fufa; NCollection_List<TopoDS_Shape> ldum; int addinternal = 1; // disparition
// clang-format on
fufa.Init(ldum, *GLOBAL_lfr1, addinternal);
fufa.PerformFace();
bool isdone = fufa.IsDone();
if (!isdone)
{
return;
}
#ifdef OCCT_DEBUG
// bool ismodified = fufa.IsModified();
#endif
const NCollection_List<TopoDS_Shape>& lfr2 = fufa.LFuseFace();
//
// const NCollection_List<TopoDS_Shape>& lfr2 = *GLOBAL_lfr1
// les faces remplacantes
for (NCollection_List<TopoDS_Shape>::Iterator itlfr2(lfr2); itlfr2.More(); itlfr2.Next())
{
const TopoDS_Shape& flfr2 = itlfr2.Value();
#ifdef OCCT_DEBUG
if (tSPS)
{
DEBSHASET(ss, "--- FillFaceSFS apres fufa", SFS, " AddStartElement SFS+ face ");
GdumpSHA(flfr2, (void*)ss.ToCString());
std::cout << " ";
TopAbs::Print(TB1, std::cout) << " : 1 face ";
TopAbs::Print(flfr2.Orientation(), std::cout);
std::cout << std::endl;
}
#endif
SFS.AddStartElement(flfr2);
}
} // performfufa (context)
} // makemerge
} // tosplit && tomerge
else if (tosplit && !tomerge)
{
GSplitFace(FOR, Gin, LSO2);
GSplitFaceSFS(FOR, LSO2, Gin, SFS);
}
else if (!tosplit && !tomerge)
{
GSplitFaceSFS(FOR, LSO2, Gin, SFS);
}
myEdgeAvoid.Clear();
#ifdef OCCT_DEBUG
if (tSPS)
{
GdumpSHASTA(FOR, TB1, "--- GFillFaceSFS END ");
std::cout << std::endl;
}
#endif
} // GFillFaceSFS