Loading files
// Created on: 1999-01-04
// Created by: Xuan PHAM PHU
// Copyright (c) 1997-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 <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopOpeBRepTool_CLASSI.hxx>
#include <TopOpeBRepTool_GEOMETRY.hxx>
#include <TopOpeBRepTool_PROJECT.hxx>
#include <TopOpeBRepTool_TOPOLOGY.hxx>
#include <TopOpeBRepTool_REGUS.hxx>
#include <TopOpeBRepTool_REGUW.hxx>
#include <TopOpeBRepTool_TOOL.hxx>
#define M_FORWARD(ori) (ori == TopAbs_FORWARD)
#define M_REVERSED(ori) (ori == TopAbs_REVERSED)
#define M_INTERNAL(ori) (ori == TopAbs_INTERNAL)
#define M_EXTERNAL(ori) (ori == TopAbs_EXTERNAL)
#define FORWARD (1)
#define REVERSED (2)
#define INTERNAL (3)
#define EXTERNAL (4)
#define CLOSING (5)
#ifdef OCCT_DEBUG
extern bool TopOpeBRepTool_GettraceREGUSO();
static NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> STATIC_mape, STATIC_mapf,
STATIC_mapw, STATIC_mapsh;
static int FUN_adds(const TopoDS_Shape& s)
{
TopAbs_ShapeEnum typ = s.ShapeType();
TCollection_AsciiString aa;
int is = 0;
if (typ == TopAbs_SHELL)
{
aa = TCollection_AsciiString("s");
is = STATIC_mapsh.Add(s);
}
if (typ == TopAbs_WIRE)
{
aa = TCollection_AsciiString("w");
is = STATIC_mapw.Add(s);
}
if (typ == TopAbs_FACE)
{
aa = TCollection_AsciiString("f");
is = STATIC_mapf.Add(s);
}
if (typ == TopAbs_EDGE)
{
aa = TCollection_AsciiString("e");
is = STATIC_mape.Add(s);
}
return is;
}
#endif
static void FUN_Raise()
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
if (trc)
std::cout << "***** Failure in REGUS **********" << std::endl;
// throw Standard_Failure("REGUS");
#endif
}
//=================================================================================================
TopOpeBRepTool_REGUS::TopOpeBRepTool_REGUS()
{
hasnewsplits = false;
mynF = myoldnF = 0;
myFsplits.Clear();
myOshNsh.Clear();
myS.Nullify();
mymapeFs.Clear();
mymapeFsstatic.Clear();
mymapemult.Clear();
myedstoconnect.Clear();
}
//=================================================================================================
void TopOpeBRepTool_REGUS::Init(const TopoDS_Shape& S)
{
hasnewsplits = false;
mynF = myoldnF = 0;
myS = S;
mymapeFs.Clear();
mymapeFsstatic.Clear();
mymapemult.Clear();
myedstoconnect.Clear();
}
//=================================================================================================
const TopoDS_Shape& TopOpeBRepTool_REGUS::S() const
{
return myS;
}
//=================================================================================================
void TopOpeBRepTool_REGUS::SetFsplits(
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>&
Fsplits)
{
myFsplits = Fsplits;
}
//=================================================================================================
void TopOpeBRepTool_REGUS::GetFsplits(
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>&
Fsplits) const
{
Fsplits = myFsplits;
}
//=================================================================================================
void TopOpeBRepTool_REGUS::SetOshNsh(
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>&
OshNsh)
{
myOshNsh = OshNsh;
}
//=================================================================================================
void TopOpeBRepTool_REGUS::GetOshNsh(
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>&
OshNsh) const
{
OshNsh = myOshNsh;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::MapS()
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
int ish = FUN_adds(S());
if (trc)
std::cout << "** MAPPING ** shape" << ish << std::endl;
#endif
// mymapeFs, myoldnF :
myoldnF = 0;
TopExp_Explorer exf(myS, TopAbs_FACE);
for (; exf.More(); exf.Next())
{
const TopoDS_Shape& f = exf.Current();
myoldnF++;
TopExp_Explorer exe(f, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Shape& e = exe.Current();
bool isb = mymapeFs.IsBound(e);
if (isb)
{
mymapeFs.ChangeFind(e).Append(f);
mymapeFsstatic.ChangeFind(e).Append(f);
}
else
{
NCollection_List<TopoDS_Shape> lof;
lof.Append(f);
mymapeFs.Bind(e, lof);
mymapeFsstatic.Bind(e, lof);
}
} // exe
} // exf
mynF = myoldnF;
// mymapemult :
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>::
Iterator itm(mymapeFs);
for (; itm.More(); itm.Next())
{
const TopoDS_Shape& e = itm.Key();
const NCollection_List<TopoDS_Shape>& lof = itm.Value();
int nf = lof.Extent();
if (nf > 2)
{
mymapemult.Add(e);
}
#ifdef OCCT_DEBUG
if (trc)
{
std::cout << "co(e" << FUN_adds(e) << ")= ";
NCollection_List<TopoDS_Shape>::Iterator it(lof);
for (; it.More(); it.Next())
std::cout << " f" << FUN_adds(it.Value());
std::cout << std::endl;
}
#endif
} // itm(mymapeFs)
return true;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::WireToFace(const TopoDS_Face& Fanc,
const NCollection_List<TopoDS_Shape>& nWs,
NCollection_List<TopoDS_Shape>& nFs)
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
#endif
nFs.Clear();
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>
mapWlow;
TopoDS_Shape aLocalShape = Fanc.Oriented(TopAbs_FORWARD);
TopoDS_Face aFace = TopoDS::Face(aLocalShape);
// TopoDS_Face aFace = TopoDS::Face(Fanc.Oriented(TopAbs_FORWARD));
TopOpeBRepTool_CLASSI classi;
classi.Init2d(aFace);
bool classifok = classi.Classilist(nWs, mapWlow);
if (!classifok)
{
#ifdef OCCT_DEBUG
if (trc)
std::cout << "** classif fails" << std::endl;
#endif
return false;
}
bool facesbuilt = TopOpeBRepTool_TOOL::WireToFace(Fanc, mapWlow, nFs);
return facesbuilt;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::SplitF(const TopoDS_Face& Fanc, NCollection_List<TopoDS_Shape>& FSplits)
{
// prequesitory : All edges have already been split, there is no
// internal vertex on edge, except for internal edge.
TopAbs_Orientation oAnc = Fanc.Orientation();
TopoDS_Shape aLocalShapeFromFace = Fanc.Oriented(TopAbs_FORWARD);
TopoDS_Face aFace = TopoDS::Face(aLocalShapeFromFace);
// TopoDS_Face aFace = TopoDS::Face(Fanc.Oriented(TopAbs_FORWARD));
FSplits.Clear();
TopOpeBRepTool_REGUW REGUW(aFace);
NCollection_List<TopoDS_Shape> nWs;
bool hassp = false;
TopExp_Explorer exw(aFace, TopAbs_WIRE);
for (; exw.More(); exw.Next())
{
const TopoDS_Shape& w = exw.Current();
REGUW.Init(w);
REGUW.MapS();
NCollection_List<TopoDS_Shape> eIs;
// --------
TopExp_Explorer exe(w, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Shape& e = exe.Current();
if (M_INTERNAL(e.Orientation()))
{
eIs.Append(e);
}
} // exe
NCollection_List<TopoDS_Shape>::Iterator ite(eIs);
// if (!ite.More()) {nWs.Append(w); continue;}
while (ite.More())
{
const TopoDS_Edge& eI = TopoDS::Edge(ite.Value());
TopoDS_Vertex vf, vl;
TopoDS_Shape aLocalShape = eI.Oriented(TopAbs_FORWARD);
TopExp::Vertices(TopoDS::Edge(aLocalShape), vf, vl);
// TopExp::Vertices(TopoDS::Edge(eI.Oriented(TopAbs_FORWARD)),vf,vl);
TopOpeBRepTool_connexity cof;
REGUW.Connexity(vf, cof);
NCollection_List<TopoDS_Shape> lef;
int nef = cof.AllItems(lef);
TopOpeBRepTool_connexity col;
REGUW.Connexity(vl, col);
NCollection_List<TopoDS_Shape> lel;
int nel = col.AllItems(lel);
if ((nef <= 1) || (nel <= 1))
{
eIs.Remove(ite);
continue;
}
// prequesitory : we do not have internal vertices in edges oriented FOR
aLocalShape = eI.Oriented(TopAbs_REVERSED);
TopoDS_Edge eR = TopoDS::Edge(aLocalShape);
aLocalShape = eI.Oriented(TopAbs_FORWARD);
TopoDS_Edge eF = TopoDS::Edge(aLocalShape);
// TopoDS_Edge eR = TopoDS::Edge(eI.Oriented(TopAbs_REVERSED));
// TopoDS_Edge eF = TopoDS::Edge(eI.Oriented(TopAbs_FORWARD));
TopExp_Explorer exv(eI, TopAbs_VERTEX);
for (; exv.More(); exv.Next())
{
const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
bool ok = REGUW.RemoveOldConnexity(v, INTERNAL, eI);
if (!ok)
{
return false;
}
int ivF = TopOpeBRepTool_TOOL::OriinSor(v, eF);
ok = REGUW.AddNewConnexity(v, ivF, eF);
if (!ok)
{
return false;
}
int ivR = TopOpeBRepTool_TOOL::OriinSor(v, eR);
ok = REGUW.AddNewConnexity(v, ivR, eR);
if (!ok)
{
return false;
}
ok = REGUW.UpdateMultiple(v);
if (!ok)
{
return false;
}
} // exv
ite.Next();
} // ite(eIs)
// now all edges of <eIs> are INTERNAL edges of <w>
// their 2 bounds are of connexity > 1.
// if (eIs.IsEmpty()) {nWs.Append(w); continue;}
NCollection_List<TopoDS_Shape> spW;
// --------
bool spok = REGUW.REGU(); // only first step
if (!spok)
{
FUN_Raise();
return false;
}
REGUW.GetSplits(spW);
if (!spW.IsEmpty())
{
nWs.Append(spW);
hassp = true;
}
} // exw
if (!hassp)
{
return false;
}
NCollection_List<TopoDS_Shape> nFs;
bool ok = TopOpeBRepTool_REGUS::WireToFace(aFace, nWs, nFs);
if (!ok)
{
FUN_Raise();
return false;
}
NCollection_List<TopoDS_Shape>::Iterator itf(nFs);
for (; itf.More(); itf.Next())
{
FSplits.Append(itf.Value().Oriented(oAnc));
}
return true;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::SplitFaces()
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
int ish = FUN_adds(S());
if (trc)
std::cout << "** SPLITTING FACES ** shape" << ish << std::endl;
#endif
TopExp_Explorer exf(myS, TopAbs_FACE);
for (; exf.More(); exf.Next())
{
// splitting face :
const TopoDS_Face& f = TopoDS::Face(exf.Current());
NCollection_List<TopoDS_Shape> lfsp;
bool issp = TopOpeBRepTool_REGUS::SplitF(f, lfsp);
if (!issp)
{
continue;
}
myFsplits.Bind(f, lfsp);
// updating the map of connexity :
// f -> lfsp = {fsp}
mynF--;
NCollection_List<TopoDS_Shape>::Iterator itf(lfsp);
for (; itf.More(); itf.Next())
{
const TopoDS_Shape& fsp = itf.Value();
mynF++;
TopExp_Explorer exe(fsp, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
// fsp -> {e}
const TopoDS_Shape& e = exe.Current();
bool isb = mymapeFs.IsBound(e);
if (!isb)
{
FUN_Raise();
return false;
}
// <mymapeFs>
NCollection_List<TopoDS_Shape>& lof = mymapeFs.ChangeFind(e);
TopOpeBRepTool_TOOL::Remove(lof, f);
lof.Append(fsp);
// <mymapemult>
int nf = lof.Extent();
if (nf > 2)
{
mymapemult.Add(e);
}
} // exe(fsp)
} // itf(lfsp)
#ifdef OCCT_DEBUG
if (trc)
{
std::cout << "split(f" << FUN_adds(f) << ")= ";
NCollection_List<TopoDS_Shape>::Iterator it(lfsp);
for (; it.More(); it.Next())
std::cout << " f" << FUN_adds(it.Value());
std::cout << std::endl;
}
#endif
} // exf(myS)
return true;
}
static void FUN_update(const TopoDS_Shape& fcur,
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher>& edstoconnect)
// purpose : <e> edge of <fcur>
// 1. <e> is INTERNAL or EXTERNAL -> nothing is done
// 2. <e> is closing edge of <fcur> -> nothing is done
// 3. <e> is already bound in <edstoconnect> -> remove it from the map
// (then has 2 ancestor faces stored in the current Block)
// 4. elsewhere, add it in the map.
//
// !! if <fcur> is INTERNAL/EXTERNAL -> nothing is done
{
TopAbs_Orientation ofcur = fcur.Orientation();
if (M_INTERNAL(ofcur) || M_EXTERNAL(ofcur))
{
return;
}
TopExp_Explorer exe(fcur, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Shape& e = exe.Current();
TopAbs_Orientation oe = e.Orientation();
if (M_INTERNAL(oe) || M_EXTERNAL(oe))
{
continue;
}
bool isclo = TopOpeBRepTool_TOOL::IsClosingE(TopoDS::Edge(e), TopoDS::Face(fcur));
if (isclo)
{
continue;
}
bool isb = edstoconnect.Contains(e);
if (isb)
{
edstoconnect.Remove(e);
}
else
{
edstoconnect.Add(e);
}
} // exe
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::REGU()
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
int ishe = FUN_adds(myS);
if (trc)
std::cout << "** REGU **" << ishe << std::endl;
#endif
NCollection_List<TopoDS_Shape> Splits;
bool toregu = !mymapemult.IsEmpty() || (mynF != myoldnF);
if (!toregu)
{
return false;
}
// purpose : myS -> {Blocks},
// a Block is a closed shell with "valid" edges.
// - a valid edge in a Block has at most two ancestor faces -
//
// Give us the starting couple (<ei>, <fi>) :
// * If <ei> has only one untouched ancestor face <fj> left, fj+1 <- fj
// Else among the untouched ancestors faces, we choose the one for which
// angle (<veci>, <vecj>) is the smallest; providing face <fj> reduces
// the matter described by <fi>.
// * update <mymapeFs> for <ei> (<fj> as touched).
// * Update <mymapemult> for <fi>'s bound edges :
// - if bound edge is not in the map, add it.
// - else if bound edge has two ancestor faces in current list <mylFinBlock>,
// delete it form the map.
//
// NCollection_List<TopoDS_Shape> lFinBlock; // <lFinBlock> describes a valid closed shell when
// <myedstoconnect> is emptied.
mylFinBlock.Clear();
int nite = 0;
while (nite <= mynF)
{
bool startBlock = mylFinBlock.IsEmpty();
bool endBlock = myedstoconnect.IsEmpty() && (!startBlock);
#ifdef OCCT_DEBUG
bool tr = false;
if (tr)
{
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher>::Iterator it(myedstoconnect);
std::cout << "still to connect : ";
for (; it.More(); it.Next())
std::cout << " e" << FUN_adds(it.Key());
std::cout << std::endl;
}
#endif
//* endBlock
// ---------
if (endBlock)
{
// building up shell on <mylFinBlock>
int nFcur = mylFinBlock.Extent();
bool unchanged = (nFcur == myoldnF) && (mynF == myoldnF);
if (unchanged)
{
#ifdef OCCT_DEBUG
if (trc)
std::cout << "#** shell" << ishe << " valid\n";
#endif
return false; // nyi analysis if we should raise or not
}
else
{
TopoDS_Shell newShe;
TopOpeBRepTool_TOOL::MkShell(mylFinBlock, newShe);
Splits.Append(newShe);
#ifdef OCCT_DEBUG
if (trc)
{
std::cout << "#** shell " << ishe << " gives new shell " << FUN_adds(newShe) << std::endl;
for (NCollection_List<TopoDS_Shape>::Iterator it(mylFinBlock); it.More(); it.Next())
std::cout << ";dins f" << FUN_adds(it.Value());
std::cout << std::endl << std::endl;
}
#endif
mylFinBlock.Clear();
startBlock = true;
}
} // endBlock
//* all faces touched
// ------------------
bool FINI = (nite == mynF);
if (FINI)
{
break;
}
int advance = false;
//* initializing a new Block
// -------------------------
if (startBlock || endBlock)
{
advance = InitBlock();
if (!advance)
{
return false;
}
} // startBlock||endBlock
//* choosing next face
// -------------------
else
{
advance = NextinBlock();
}
// ** updating connexity
::FUN_update(myf, myedstoconnect);
if (!advance)
{
endBlock = myedstoconnect.IsEmpty() && (!startBlock);
if (!endBlock)
{
return false;
}
else
{
continue;
}
}
TopExp_Explorer exe(myf, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Shape& e = exe.Current();
bool isb = mymapeFs.IsBound(e);
if (!isb)
{
continue; // ancestors faces of <e> are stored in Blocks
}
TopOpeBRepTool_TOOL::Remove(mymapeFs.ChangeFind(e), myf);
} // exe
mylFinBlock.Append(myf);
nite++;
} // nite <= mynF
myOshNsh.Bind(S(), Splits);
return true;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::InitBlock()
{
int nec = myedstoconnect.Extent();
if (nec != 0)
{
return false; // should be empty
}
NCollection_List<TopoDS_Shape> eds;
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>::
Iterator itm(mymapeFs);
for (; itm.More(); itm.Next())
{
eds.Append(itm.Key());
}
NCollection_List<TopoDS_Shape>::Iterator ite(eds);
for (; ite.More(); ite.Next())
{
const TopoDS_Shape& e = ite.Value();
const NCollection_List<TopoDS_Shape>& lof = mymapeFs.Find(e);
if (lof.IsEmpty())
{
mymapeFs.UnBind(e);
continue;
}
myf = lof.First();
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
if (trc)
std::cout << "* Block : first face = f" << FUN_adds(myf) << std::endl;
#endif
return true;
}
return false;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::NextinBlock()
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
#endif
// we try to connect first edge of <myf> bound in <myedstoconnect>
NCollection_List<TopoDS_Shape> eds;
TopExp_Explorer exe(myf, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Shape& e = exe.Current();
bool isb = myedstoconnect.Contains(e);
if (isb)
{
eds.Append(e);
}
} // exe
bool alleftouched = eds.IsEmpty();
if (alleftouched)
{
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher>::Iterator itc(myedstoconnect);
for (; itc.More(); itc.Next())
{
const TopoDS_Shape& e = itc.Key();
bool isBound = mymapeFs.IsBound(e);
// all ancestor faces of <e> have been stored
if (!isBound)
{
myedstoconnect.Remove(e);
continue;
}
const NCollection_List<TopoDS_Shape>& lof = mymapeFs.Find(e);
int nf = lof.Extent();
if (nf == 0)
{
myedstoconnect.Remove(e);
mymapeFs.UnBind(e);
continue;
}
// myf = lof.First(); 130499
if (lof.Extent() == 1)
{
myf = lof.First();
}
else
{
// looking for first face stored in the current block
// connexed to e
NCollection_List<TopoDS_Shape>::Iterator itff(mylFinBlock);
NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> mapf;
for (; itff.More(); itff.Next())
{
mapf.Add(itff.Value());
}
// lofc : the list of faces connexed to e in <myS>
// lof : the list of untouched faces connexed to e in <myS>
const NCollection_List<TopoDS_Shape>& lofc = mymapeFsstatic.Find(e);
itff.Initialize(lofc);
TopoDS_Face fref;
for (; itff.More(); itff.Next())
{
const TopoDS_Face& fc = TopoDS::Face(itff.Value());
bool isb = mapf.Contains(fc);
if (isb)
{
fref = fc;
break;
}
} // itff(lofc)
if (fref.IsNull())
{
return false; // !!!!!!!!!! a revoir 130499
}
else
{
myf = fref;
TopoDS_Face ffound;
bool ok = NearestF(TopoDS::Edge(e), lof, ffound);
if (!ok)
{
return false;
}
myf = ffound;
}
}
return true;
}
return false;
}
NCollection_List<TopoDS_Shape>::Iterator ite(eds);
for (; ite.More(); ite.Next())
{
const TopoDS_Shape& e = ite.Value();
bool isb = mymapeFs.IsBound(e);
// all ancestor faces of <e> have been stored
if (!isb)
{
myedstoconnect.Remove(e);
continue;
}
const NCollection_List<TopoDS_Shape>& lof = mymapeFs.Find(e);
int nf = lof.Extent();
if (nf == 0)
{
myedstoconnect.Remove(e);
mymapeFs.UnBind(e);
continue;
}
#ifdef OCCT_DEBUG
if (trc)
{
std::cout << "e" << FUN_adds(e) << " on " << nf << " untouched f:" << std::endl;
}
#endif
if (nf == 1)
{
myf = lof.First();
}
else
{
TopoDS_Face ffound;
bool ok = NearestF(TopoDS::Edge(e), lof, ffound);
if (!ok)
{
return false;
}
myf = ffound;
}
#ifdef OCCT_DEBUG
if (trc)
std::cout << "->myf = f" << FUN_adds(myf) << std::endl;
#endif
return true;
} // itm(myedstoconnect)
return false;
}
static bool FUN_vectors(const TopoDS_Face& f,
const TopoDS_Edge& e,
const double pare,
gp_Dir& nt,
gp_Dir& xx,
const double tola,
const bool approx)
{
// <nt> :
if (approx)
{
bool ok = TopOpeBRepTool_TOOL::tryNgApp(pare, e, f, tola, nt);
if (!ok)
{
return false;
}
}
else
{
gp_Vec tmp;
bool ok = FUN_tool_nggeomF(pare, e, f, tmp);
if (!ok)
{
return false;
}
nt = gp_Dir(tmp);
}
if (M_REVERSED(f.Orientation()))
{
nt.Reverse();
}
// <xx> :
bool ok = FUN_tool_getxx(f, e, pare, xx);
return ok;
}
//=================================================================================================
bool TopOpeBRepTool_REGUS::NearestF(const TopoDS_Edge& e,
const NCollection_List<TopoDS_Shape>& lof,
TopoDS_Face& ffound) const
// prequesitory : <e> is shared by <myf> and faces of <lof>.
//
// NYIXPU!!!!!!!! if (xx1 tg xx2) -> use curvatures
//
{
#ifdef OCCT_DEBUG
bool trc = TopOpeBRepTool_GettraceREGUSO();
#endif
ffound.Nullify();
TopoDS_Face fref = TopoDS::Face(myf);
// Give us edge <e>, and a reference face <fref> (= <myf>)
// - parameter on <e> = <pare>.
// - xxi = tangent fo face fi at pnt(e,pare) oriented INSIDE 2d(fi)
// normal to tge = tg(e,pare).
// purpose : looking for ffound /
// MatterAng(xxref, xxfound) = Min{ MatterAng(xxref, xxi), xxi for fi in <lof>
// providing fi reduces 3d(fref) }
// <parone> :
double f, l;
FUN_tool_bounds(e, f, l);
double eps = 0.45678;
double pare = (1 - eps) * f + eps * l;
// RONd (x,y,z) = (xxref,ntref,x^y)
// clang-format off
double tola = Precision::Angular()*1.e3; //gp_Dir xapp,yapp; bool refapp = false;
// clang-format on
gp_Dir x, y;
bool ok = ::FUN_vectors(fref, e, pare, y, x, tola, false);
if (!ok)
{
FUN_Raise();
return false;
}
// initializing
// ------------
double angfound = 0;
NCollection_List<TopoDS_Shape>::Iterator itf(lof);
for (; itf.More(); itf.Next())
{
ffound = TopoDS::Face(itf.Value());
gp_Dir ntfound, xxfound;
ok = ::FUN_vectors(ffound, e, pare, ntfound, xxfound, tola, false);
if (!ok)
{
FUN_Raise();
return false;
}
bool oppo = TopOpeBRepTool_TOOL::Matter(x, y, xxfound, ntfound, tola, angfound);
#ifdef OCCT_DEBUG
if (trc && !oppo)
std::cout << " f" << FUN_adds(fref) << ",f" << FUN_adds(ffound) << " not oppo" << std::endl;
#endif
if (!oppo)
{
ffound.Nullify();
continue;
}
if (angfound < tola)
{
// refapp = true; ::FUN_vectors(fref,e,pare,yapp,xapp,tola,true);
// ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,true);
// TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxfound,ntfound,tola, angfound);
ok = TopOpeBRepTool_TOOL::MatterKPtg(fref, ffound, e, angfound);
if (!ok)
{
FUN_Raise();
return false;
}
}
#ifdef OCCT_DEBUG
if (trc)
std::cout << " ang(f" << FUN_adds(fref) << ",f" << FUN_adds(ffound) << ")=" << angfound
<< std::endl;
#endif
break;
}
if (ffound.IsNull())
{
FUN_Raise();
return false;
}
if (itf.More())
{
itf.Next();
}
else
{
return true;
}
// selecting nearest face
// ----------------------
for (; itf.More(); itf.Next())
{
gp_Dir nti, xxi;
const TopoDS_Face& fi = TopoDS::Face(itf.Value());
ok = ::FUN_vectors(fi, e, pare, nti, xxi, tola, false);
if (!ok)
{
FUN_Raise();
return false;
}
double angi = 0;
bool oppo = TopOpeBRepTool_TOOL::Matter(x, y, xxi, nti, tola, angi);
#ifdef OCCT_DEBUG
if (trc && !oppo)
std::cout << " f" << FUN_adds(fref) << ",f" << FUN_adds(fi) << " not oppo" << std::endl;
#endif
if (!oppo)
{
continue;
}
if (angi < tola)
{
// if (!refapp) ::FUN_vectors(fref,e,pare,yapp,xapp,tola,true);
// ::FUN_vectors(fi,e,pare,nti,xxi,tola,true);
// TopOpeBRepTool_TOOL::Matter(xapp,yapp,xxi,nti,tola, angi);
ok = TopOpeBRepTool_TOOL::MatterKPtg(fref, fi, e, angi);
if (!ok)
{
FUN_Raise();
return false;
}
}
#ifdef OCCT_DEBUG
if (trc)
std::cout << " ang(f" << FUN_adds(fref) << ",f" << FUN_adds(fi) << ")=" << angi
<< std::endl;
#endif
if (angi > angfound)
{
continue;
}
angfound = angi;
ffound = fi;
}
return true;
}
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.