[TD]fix area calculation
This commit is contained in:
committed by
Yorik van Havre
parent
6c85c37b38
commit
1de4dc600d
@@ -82,9 +82,11 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include <Mod/Part/App/FaceMakerCheese.h>
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
|
||||
#include "DrawViewPart.h"
|
||||
#include "Geometry.h"
|
||||
#include "ShapeUtils.h"
|
||||
#include "DrawUtil.h"
|
||||
@@ -145,10 +147,14 @@ void Wire::dump(std::string s)
|
||||
BRepTools::Write(toOccWire(), s.c_str()); //debug
|
||||
}
|
||||
|
||||
// note that the face returned is inverted in Y
|
||||
TopoDS_Face Face::toOccFace() const
|
||||
{
|
||||
if (wires.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
TopoDS_Face result;
|
||||
//if (!wires.empty) {
|
||||
BRepBuilderAPI_MakeFace mkFace(wires.front()->toOccWire(), true);
|
||||
int limit = wires.size();
|
||||
int iwire = 1;
|
||||
@@ -1734,3 +1740,105 @@ double GeometryUtils::edgeLength(TopoDS_Edge occEdge)
|
||||
}
|
||||
}
|
||||
|
||||
//! return a perforated shape/face (using Part::FaceMakerCheese) formed by creating holes in the input face.
|
||||
TopoDS_Face GeometryUtils::makePerforatedFace(FacePtr bigCheese, const std::vector<FacePtr> &holesAll)
|
||||
{
|
||||
std::vector<TopoDS_Wire> cheeseIngredients;
|
||||
|
||||
// v0.0 brute force
|
||||
|
||||
// Note: TD Faces are not perforated and should only ever have 1 wire. They are capable of
|
||||
// having voids, but for now we will just take the first contour wire in all cases.
|
||||
|
||||
if (bigCheese->wires.empty()) {
|
||||
// run in circles. scream and shout.
|
||||
return {};
|
||||
}
|
||||
|
||||
auto flippedFace = ShapeUtils::fromQtAsFace(bigCheese->toOccFace());
|
||||
|
||||
if (holesAll.empty()) {
|
||||
return flippedFace;
|
||||
}
|
||||
|
||||
auto outer = ShapeUtils::fromQtAsWire(bigCheese->wires.front()->toOccWire());
|
||||
cheeseIngredients.push_back(outer);
|
||||
for (auto& hole : holesAll) {
|
||||
if (hole->wires.empty()) {
|
||||
continue;
|
||||
}
|
||||
auto holeR3 = ShapeUtils::fromQtAsWire(hole->wires.front()->toOccWire());
|
||||
cheeseIngredients.push_back(holeR3);
|
||||
}
|
||||
|
||||
TopoDS_Shape faceShape;
|
||||
try {
|
||||
faceShape = Part::FaceMakerCheese::makeFace(cheeseIngredients);
|
||||
}
|
||||
catch (const Standard_Failure &e) {
|
||||
Base::Console().Warning("Area - could not make holes in face\n");
|
||||
return flippedFace;
|
||||
}
|
||||
|
||||
|
||||
// v0.0 just grab the first face
|
||||
TopoDS_Face foundFace;
|
||||
TopExp_Explorer expFaces(faceShape, TopAbs_FACE);
|
||||
if (expFaces.More()) {
|
||||
foundFace = TopoDS::Face(expFaces.Current());
|
||||
}
|
||||
// TODO: sort out the compound => shape but !compound => face business in FaceMakerCheese here.
|
||||
// first guess is it does not affect us?
|
||||
|
||||
return foundFace;
|
||||
}
|
||||
|
||||
|
||||
//! find faces within the bounds of the input face
|
||||
std::vector<FacePtr> GeometryUtils::findHolesInFace(const DrawViewPart* dvp, const std::string& bigCheeseSubRef)
|
||||
{
|
||||
if (!dvp || bigCheeseSubRef.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<FacePtr> holes;
|
||||
auto bigCheeseIndex = DU::getIndexFromName(bigCheeseSubRef);
|
||||
|
||||
// v0.0 brute force
|
||||
auto facesAll = dvp->getFaceGeometry();
|
||||
if (facesAll.empty()) {
|
||||
// tarfu
|
||||
throw Base::RuntimeError("GU::findHolesInFace - no holes to find!!");
|
||||
}
|
||||
|
||||
auto bigCheeseFace = facesAll.at(bigCheeseIndex);
|
||||
auto bigCheeseOCCFace = bigCheeseFace->toOccFace();
|
||||
auto bigCheeseArea = bigCheeseFace->getArea();
|
||||
|
||||
int iFace{0};
|
||||
for (auto& face : facesAll) {
|
||||
if (iFace == bigCheeseIndex) {
|
||||
iFace++;
|
||||
continue;
|
||||
}
|
||||
if (face->getArea() > bigCheeseArea) {
|
||||
iFace++;
|
||||
continue;
|
||||
}
|
||||
auto faceCenter = DU::togp_Pnt(face->getCenter());
|
||||
auto faceCenterVertex = BRepBuilderAPI_MakeVertex(faceCenter);
|
||||
auto distance = DU::simpleMinDist(faceCenterVertex, bigCheeseOCCFace);
|
||||
if (distance > EWTOLERANCE) {
|
||||
// hole center not within outer contour. not the best test but cheese maker handles it
|
||||
// for us?
|
||||
// FaceMakerCheese does not support partial overlaps and just ignores them?
|
||||
iFace++;
|
||||
continue;
|
||||
}
|
||||
holes.push_back(face);
|
||||
iFace++;
|
||||
}
|
||||
|
||||
return holes;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user