FreeCAD/src/Mod/Mesh/App/Mesh.cpp

1804 lines
55 KiB
C++

/***************************************************************************
* Copyright (c) Juergen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <sstream>
#endif
#include <CXX/Objects.hxx>
#include <Base/Builder3D.h>
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Interpreter.h>
#include <Base/Sequencer.h>
#include <Base/ViewProj.h>
#include "Core/Builder.h"
#include "Core/MeshKernel.h"
#include "Core/Grid.h"
#include "Core/Iterator.h"
#include "Core/Info.h"
#include "Core/TopoAlgorithm.h"
#include "Core/Evaluation.h"
#include "Core/Degeneration.h"
#include "Core/Segmentation.h"
#include "Core/SetOperations.h"
#include "Core/Triangulation.h"
#include "Core/Trim.h"
#include "Core/Visitor.h"
#include "Mesh.h"
#include "MeshPy.h"
using namespace Mesh;
float MeshObject::Epsilon = 1.0e-5f;
TYPESYSTEM_SOURCE(Mesh::MeshObject, Data::ComplexGeoData);
MeshObject::MeshObject()
{
}
MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel)
: _kernel(Kernel)
{
// copy the mesh structure
}
MeshObject::MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D &Mtrx)
: _Mtrx(Mtrx),_kernel(Kernel)
{
// copy the mesh structure
}
MeshObject::MeshObject(const MeshObject& mesh)
: _Mtrx(mesh._Mtrx),_kernel(mesh._kernel)
{
// copy the mesh structure
this->_segments = mesh._segments;
}
MeshObject::~MeshObject()
{
}
std::vector<const char*> MeshObject::getElementTypes(void) const
{
std::vector<const char*> temp;
temp.push_back("Face"); // that's the mesh itself
temp.push_back("Segment");
return temp;
}
unsigned long MeshObject::countSubElements(const char* Type) const
{
std::string element(Type);
if (element == "Face")
return 1;
else if (element == "Segment")
return countSegments();
return 0;
}
Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long n) const
{
//TODO
std::string element(Type);
if (element == "Face")
return 0;
else if (element == "Segment")
return 0;
return 0;
}
void MeshObject::getFacesFromSubelement(const Data::Segment* segm,
std::vector<Base::Vector3d> &Points,
std::vector<Base::Vector3d> &PointNormals,
std::vector<Facet> &faces) const
{
//TODO
this->getFaces(Points, faces, 0.0f);
}
void MeshObject::transformGeometry(const Base::Matrix4D &rclMat)
{
MeshCore::MeshKernel kernel;
swap(kernel);
kernel.Transform(rclMat);
swap(kernel);
}
void MeshObject::setTransform(const Base::Matrix4D& rclTrf)
{
_Mtrx = rclTrf;
}
Base::Matrix4D MeshObject::getTransform(void) const
{
return _Mtrx;
}
Base::BoundBox3d MeshObject::getBoundBox(void)const
{
const_cast<MeshCore::MeshKernel&>(_kernel).RecalcBoundBox();
Base::BoundBox3f Bnd = _kernel.GetBoundBox();
Base::BoundBox3d Bnd2;
if (Bnd.IsValid()) {
for (int i =0 ;i<=7;i++)
Bnd2.Add(transformToOutside(Bnd.CalcPoint(i)));
}
return Bnd2;
}
void MeshObject::operator = (const MeshObject& mesh)
{
if (this != &mesh) {
// copy the mesh structure
setTransform(mesh._Mtrx);
this->_kernel = mesh._kernel;
this->_segments = mesh._segments;
}
}
void MeshObject::setKernel(const MeshCore::MeshKernel& m)
{
this->_kernel = m;
this->_segments.clear();
}
void MeshObject::swap(MeshCore::MeshKernel& Kernel)
{
this->_kernel.Swap(Kernel);
// clear the segments because we don't know how the new
// topology looks like
this->_segments.clear();
}
void MeshObject::swap(MeshObject& mesh)
{
this->_kernel.Swap(mesh._kernel);
this->_segments.swap(mesh._segments);
Base::Matrix4D tmp=this->_Mtrx;
this->_Mtrx = mesh._Mtrx;
mesh._Mtrx = tmp;
}
std::string MeshObject::representation() const
{
std::stringstream str;
MeshCore::MeshInfo info(_kernel);
info.GeneralInformation(str);
return str.str();
}
std::string MeshObject::topologyInfo() const
{
std::stringstream str;
MeshCore::MeshInfo info(_kernel);
info.TopologyInformation(str);
return str.str();
}
unsigned long MeshObject::countPoints() const
{
return _kernel.CountPoints();
}
unsigned long MeshObject::countFacets() const
{
return _kernel.CountFacets();
}
unsigned long MeshObject::countEdges () const
{
return _kernel.CountEdges();
}
unsigned long MeshObject::countSegments () const
{
return this->_segments.size();
}
bool MeshObject::isSolid() const
{
MeshCore::MeshEvalSolid cMeshEval(_kernel);
return cMeshEval.Evaluate();
}
double MeshObject::getSurface() const
{
return _kernel.GetSurface();
}
double MeshObject::getVolume() const
{
return _kernel.GetVolume();
}
MeshPoint MeshObject::getPoint(unsigned long index) const
{
Base::Vector3f vertf = _kernel.GetPoint(index);
Base::Vector3d vertd(vertf.x, vertf.y, vertf.z);
vertd = _Mtrx * vertd;
MeshPoint point(vertd, const_cast<MeshObject*>(this), index);
return point;
}
void MeshObject::getPoints(std::vector<Base::Vector3d> &Points,
std::vector<Base::Vector3d> &Normals,
float Accuracy, uint16_t flags) const
{
Base::Matrix4D mat = _Mtrx;
unsigned long ctpoints = _kernel.CountPoints();
Points.reserve(ctpoints);
for (unsigned long i=0; i<ctpoints; i++) {
Base::Vector3f vertf = _kernel.GetPoint(i);
Base::Vector3d vertd(vertf.x, vertf.y, vertf.z);
vertd = mat * vertd;
Points.push_back(vertd);
}
// nullify translation part
mat[0][3] = 0.0;
mat[1][3] = 0.0;
mat[2][3] = 0.0;
Normals.reserve(ctpoints);
MeshCore::MeshRefNormalToPoints ptNormals(_kernel);
for (unsigned long i=0; i<ctpoints; i++) {
Base::Vector3f normalf = ptNormals[i];
Base::Vector3d normald(normalf.x, normalf.y, normalf.z);
normald = mat * normald;
Normals.push_back(normald);
}
}
Mesh::Facet MeshObject::getFacet(unsigned long index) const
{
Mesh::Facet face(_kernel.GetFacets()[index], const_cast<MeshObject*>(this), index);
return face;
}
void MeshObject::getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &Topo,
float Accuracy, uint16_t flags) const
{
unsigned long ctpoints = _kernel.CountPoints();
Points.reserve(ctpoints);
for (unsigned long i=0; i<ctpoints; i++) {
Points.push_back(this->getPoint(i));
}
unsigned long ctfacets = _kernel.CountFacets();
const MeshCore::MeshFacetArray& ary = _kernel.GetFacets();
Topo.reserve(ctfacets);
for (unsigned long i=0; i<ctfacets; i++) {
Facet face;
face.I1 = (unsigned int)ary[i]._aulPoints[0];
face.I2 = (unsigned int)ary[i]._aulPoints[1];
face.I3 = (unsigned int)ary[i]._aulPoints[2];
Topo.push_back(face);
}
}
unsigned int MeshObject::getMemSize (void) const
{
return _kernel.GetMemSize();
}
void MeshObject::Save (Base::Writer &writer) const
{
// this is handled by the property class
}
void MeshObject::SaveDocFile (Base::Writer &writer) const
{
_kernel.Write(writer.Stream());
}
void MeshObject::Restore(Base::XMLReader &reader)
{
// this is handled by the property class
}
void MeshObject::RestoreDocFile(Base::Reader &reader)
{
load(reader);
}
void MeshObject::save(const char* file, MeshCore::MeshIO::Format f,
const MeshCore::Material* mat,
const char* objectname) const
{
MeshCore::MeshOutput aWriter(this->_kernel, mat);
if (objectname)
aWriter.SetObjectName(objectname);
// go through the segment list and put them to the exporter when
// the "save" flag is set
std::vector<MeshCore::Group> groups;
for (std::size_t index = 0; index < this->_segments.size(); index++) {
if (this->_segments[index].isSaved()) {
MeshCore::Group g;
g.indices = this->_segments[index].getIndices();
g.name = this->_segments[index].getName();
groups.push_back(g);
}
}
aWriter.SetGroups(groups);
aWriter.Transform(this->_Mtrx);
aWriter.SaveAny(file, f);
}
void MeshObject::save(std::ostream& str, MeshCore::MeshIO::Format f,
const MeshCore::Material* mat,
const char* objectname) const
{
MeshCore::MeshOutput aWriter(this->_kernel, mat);
if (objectname)
aWriter.SetObjectName(objectname);
// go through the segment list and put them to the exporter when
// the "save" flag is set
std::vector<MeshCore::Group> groups;
for (std::size_t index = 0; index < this->_segments.size(); index++) {
if (this->_segments[index].isSaved()) {
MeshCore::Group g;
g.indices = this->_segments[index].getIndices();
g.name = this->_segments[index].getName();
groups.push_back(g);
}
}
aWriter.SetGroups(groups);
aWriter.Transform(this->_Mtrx);
aWriter.SaveFormat(str, f);
}
bool MeshObject::load(const char* file, MeshCore::Material* mat)
{
MeshCore::MeshKernel kernel;
MeshCore::MeshInput aReader(kernel, mat);
if (!aReader.LoadAny(file))
return false;
swapKernel(kernel, aReader.GetGroupNames());
return true;
}
bool MeshObject::load(std::istream& str, MeshCore::MeshIO::Format f, MeshCore::Material* mat)
{
MeshCore::MeshKernel kernel;
MeshCore::MeshInput aReader(kernel, mat);
if (!aReader.LoadFormat(str, f))
return false;
swapKernel(kernel, aReader.GetGroupNames());
return true;
}
void MeshObject::swapKernel(MeshCore::MeshKernel& kernel,
const std::vector<std::string>& g)
{
_kernel.Swap(kernel);
// Some file formats define several objects per file (e.g. OBJ).
// Now we mark each object as an own segment so that we can break
// the object into its original objects again.
this->_segments.clear();
const MeshCore::MeshFacetArray& faces = _kernel.GetFacets();
MeshCore::MeshFacetArray::_TConstIterator it;
std::vector<unsigned long> segment;
segment.reserve(faces.size());
unsigned long prop = 0;
unsigned long index = 0;
for (it = faces.begin(); it != faces.end(); ++it) {
if (prop < it->_ulProp) {
prop = it->_ulProp;
if (!segment.empty()) {
this->_segments.push_back(Segment(this,segment,true));
segment.clear();
}
}
segment.push_back(index++);
}
// if the whole mesh is a single object then don't mark as segment
if (!segment.empty() && (segment.size() < faces.size())) {
this->_segments.push_back(Segment(this,segment,true));
}
// apply the group names to the segments
if (this->_segments.size() == g.size()) {
for (std::size_t index = 0; index < this->_segments.size(); index++) {
this->_segments[index].setName(g[index]);
}
}
#ifndef FC_DEBUG
try {
MeshCore::MeshEvalNeighbourhood nb(_kernel);
if (!nb.Evaluate()) {
Base::Console().Warning("Errors in neighbourhood of mesh found...");
_kernel.RebuildNeighbours();
Base::Console().Warning("fixed\n");
}
MeshCore::MeshEvalTopology eval(_kernel);
if (!eval.Evaluate()) {
Base::Console().Warning("The mesh data structure has some defects\n");
}
}
catch (const Base::MemoryException&) {
// ignore memory exceptions and continue
Base::Console().Log("Check for defects in mesh data structure failed\n");
}
#endif
}
void MeshObject::save(std::ostream& out) const
{
_kernel.Write(out);
}
void MeshObject::load(std::istream& in)
{
_kernel.Read(in);
this->_segments.clear();
#ifndef FC_DEBUG
try {
MeshCore::MeshEvalNeighbourhood nb(_kernel);
if (!nb.Evaluate()) {
Base::Console().Warning("Errors in neighbourhood of mesh found...");
_kernel.RebuildNeighbours();
Base::Console().Warning("fixed\n");
}
MeshCore::MeshEvalTopology eval(_kernel);
if (!eval.Evaluate()) {
Base::Console().Warning("The mesh data structure has some defects\n");
}
}
catch (const Base::MemoryException&) {
// ignore memory exceptions and continue
Base::Console().Log("Check for defects in mesh data structure failed\n");
}
#endif
}
void MeshObject::addFacet(const MeshCore::MeshGeomFacet& facet)
{
_kernel.AddFacet(facet);
}
void MeshObject::addFacets(const std::vector<MeshCore::MeshGeomFacet>& facets)
{
_kernel.AddFacets(facets);
}
void MeshObject::addFacets(const std::vector<MeshCore::MeshFacet> &facets)
{
_kernel.AddFacets(facets);
}
void MeshObject::addFacets(const std::vector<MeshCore::MeshFacet> &facets,
const std::vector<Base::Vector3f>& points)
{
_kernel.AddFacets(facets, points);
}
void MeshObject::addFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
const std::vector<Base::Vector3d>& points)
{
std::vector<MeshCore::MeshFacet> facet_v;
facet_v.reserve(facets.size());
for (std::vector<Data::ComplexGeoData::Facet>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
MeshCore::MeshFacet f;
f._aulPoints[0] = it->I1;
f._aulPoints[1] = it->I2;
f._aulPoints[2] = it->I3;
facet_v.push_back(f);
}
std::vector<Base::Vector3f> point_v;
point_v.reserve(points.size());
for (std::vector<Base::Vector3d>::const_iterator it = points.begin(); it != points.end(); ++it) {
Base::Vector3f p((float)it->x,(float)it->y,(float)it->z);
point_v.push_back(p);
}
_kernel.AddFacets(facet_v, point_v);
}
void MeshObject::setFacets(const std::vector<MeshCore::MeshGeomFacet>& facets)
{
_kernel = facets;
}
void MeshObject::setFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
const std::vector<Base::Vector3d>& points)
{
MeshCore::MeshFacetArray facet_v;
facet_v.reserve(facets.size());
for (std::vector<Data::ComplexGeoData::Facet>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
MeshCore::MeshFacet f;
f._aulPoints[0] = it->I1;
f._aulPoints[1] = it->I2;
f._aulPoints[2] = it->I3;
facet_v.push_back(f);
}
MeshCore::MeshPointArray point_v;
point_v.reserve(points.size());
for (std::vector<Base::Vector3d>::const_iterator it = points.begin(); it != points.end(); ++it) {
Base::Vector3f p((float)it->x,(float)it->y,(float)it->z);
point_v.push_back(p);
}
_kernel.Adopt(point_v, facet_v, true);
}
void MeshObject::addMesh(const MeshObject& mesh)
{
_kernel.Merge(mesh._kernel);
}
void MeshObject::addMesh(const MeshCore::MeshKernel& kernel)
{
_kernel.Merge(kernel);
}
void MeshObject::deleteFacets(const std::vector<unsigned long>& removeIndices)
{
_kernel.DeleteFacets(removeIndices);
deletedFacets(removeIndices);
}
void MeshObject::deletePoints(const std::vector<unsigned long>& removeIndices)
{
_kernel.DeletePoints(removeIndices);
this->_segments.clear();
}
void MeshObject::deletedFacets(const std::vector<unsigned long>& remFacets)
{
if (remFacets.empty())
return; // nothing has changed
if (this->_segments.empty())
return; // nothing to do
// set an array with the original indices and mark the removed as ULONG_MAX
std::vector<unsigned long> f_indices(_kernel.CountFacets()+remFacets.size());
for (std::vector<unsigned long>::const_iterator it = remFacets.begin();
it != remFacets.end(); ++it) {
f_indices[*it] = ULONG_MAX;
}
unsigned long index = 0;
for (std::vector<unsigned long>::iterator it = f_indices.begin();
it != f_indices.end(); ++it) {
if (*it == 0)
*it = index++;
}
// the array serves now as LUT to set the new indices in the segments
for (std::vector<Segment>::iterator it = this->_segments.begin();
it != this->_segments.end(); ++it) {
std::vector<unsigned long> segm = it->_indices;
for (std::vector<unsigned long>::iterator jt = segm.begin();
jt != segm.end(); ++jt) {
*jt = f_indices[*jt];
}
// remove the invalid indices
std::sort(segm.begin(), segm.end());
std::vector<unsigned long>::iterator ft = std::find_if
(segm.begin(), segm.end(),
std::bind2nd(std::equal_to<unsigned long>(), ULONG_MAX));
if (ft != segm.end())
segm.erase(ft, segm.end());
it->_indices = segm;
}
}
void MeshObject::deleteSelectedFacets()
{
std::vector<unsigned long> facets;
MeshCore::MeshAlgorithm(this->_kernel).GetFacetsFlag(facets, MeshCore::MeshFacet::SELECTED);
deleteFacets(facets);
}
void MeshObject::deleteSelectedPoints()
{
std::vector<unsigned long> points;
MeshCore::MeshAlgorithm(this->_kernel).GetPointsFlag(points, MeshCore::MeshPoint::SELECTED);
deletePoints(points);
}
void MeshObject::clearFacetSelection() const
{
MeshCore::MeshAlgorithm(this->_kernel).ResetFacetFlag(MeshCore::MeshFacet::SELECTED);
}
void MeshObject::clearPointSelection() const
{
MeshCore::MeshAlgorithm(this->_kernel).ResetPointFlag(MeshCore::MeshPoint::SELECTED);
}
void MeshObject::addFacetsToSelection(const std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).SetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
}
void MeshObject::addPointsToSelection(const std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).SetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
}
void MeshObject::removeFacetsFromSelection(const std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).ResetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
}
void MeshObject::removePointsFromSelection(const std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).ResetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
}
void MeshObject::getFacetsFromSelection(std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).GetFacetsFlag(inds, MeshCore::MeshFacet::SELECTED);
}
void MeshObject::getPointsFromSelection(std::vector<unsigned long>& inds) const
{
MeshCore::MeshAlgorithm(this->_kernel).GetPointsFlag(inds, MeshCore::MeshPoint::SELECTED);
}
unsigned long MeshObject::countSelectedFacets() const
{
return MeshCore::MeshAlgorithm(this->_kernel).CountFacetFlag(MeshCore::MeshFacet::SELECTED);
}
bool MeshObject::hasSelectedFacets() const
{
return (countSelectedFacets() > 0);
}
unsigned long MeshObject::countSelectedPoints() const
{
return MeshCore::MeshAlgorithm(this->_kernel).CountPointFlag(MeshCore::MeshPoint::SELECTED);
}
bool MeshObject::hasSelectedPoints() const
{
return (countSelectedPoints() > 0);
}
std::vector<unsigned long> MeshObject::getPointsFromFacets(const std::vector<unsigned long>& facets) const
{
return _kernel.GetFacetPoints(facets);
}
void MeshObject::updateMesh(const std::vector<unsigned long>& facets)
{
std::vector<unsigned long> points;
points = _kernel.GetFacetPoints(facets);
MeshCore::MeshAlgorithm alg(_kernel);
alg.SetFacetsFlag(facets, MeshCore::MeshFacet::SEGMENT);
alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT);
}
void MeshObject::updateMesh()
{
MeshCore::MeshAlgorithm alg(_kernel);
alg.ResetFacetFlag(MeshCore::MeshFacet::SEGMENT);
alg.ResetPointFlag(MeshCore::MeshPoint::SEGMENT);
for (std::vector<Segment>::iterator it = this->_segments.begin();
it != this->_segments.end(); ++it) {
std::vector<unsigned long> points;
points = _kernel.GetFacetPoints(it->getIndices());
alg.SetFacetsFlag(it->getIndices(), MeshCore::MeshFacet::SEGMENT);
alg.SetPointsFlag(points, MeshCore::MeshPoint::SEGMENT);
}
}
std::vector<std::vector<unsigned long> > MeshObject::getComponents() const
{
std::vector<std::vector<unsigned long> > segments;
MeshCore::MeshComponents comp(_kernel);
comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments);
return segments;
}
unsigned long MeshObject::countComponents() const
{
std::vector<std::vector<unsigned long> > segments;
MeshCore::MeshComponents comp(_kernel);
comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segments);
return segments.size();
}
void MeshObject::removeComponents(unsigned long count)
{
std::vector<unsigned long> removeIndices;
MeshCore::MeshTopoAlgorithm(_kernel).FindComponents(count, removeIndices);
_kernel.DeleteFacets(removeIndices);
deletedFacets(removeIndices);
}
unsigned long MeshObject::getPointDegree(const std::vector<unsigned long>& indices,
std::vector<unsigned long>& point_degree) const
{
const MeshCore::MeshFacetArray& faces = _kernel.GetFacets();
std::vector<unsigned long> pointDeg(_kernel.CountPoints());
for (MeshCore::MeshFacetArray::_TConstIterator it = faces.begin(); it != faces.end(); ++it) {
pointDeg[it->_aulPoints[0]]++;
pointDeg[it->_aulPoints[1]]++;
pointDeg[it->_aulPoints[2]]++;
}
for (std::vector<unsigned long>::const_iterator it = indices.begin(); it != indices.end(); ++it) {
const MeshCore::MeshFacet& face = faces[*it];
pointDeg[face._aulPoints[0]]--;
pointDeg[face._aulPoints[1]]--;
pointDeg[face._aulPoints[2]]--;
}
unsigned long countInvalids = std::count_if(pointDeg.begin(), pointDeg.end(),
std::bind2nd(std::equal_to<unsigned long>(), 0));
point_degree.swap(pointDeg);
return countInvalids;
}
void MeshObject::fillupHoles(unsigned long length, int level,
MeshCore::AbstractPolygonTriangulator& cTria)
{
std::list<std::vector<unsigned long> > aFailed;
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.FillupHoles(length, level, cTria, aFailed);
}
void MeshObject::offset(float fSize)
{
std::vector<Base::Vector3f> normals = _kernel.CalcVertexNormals();
unsigned int i = 0;
// go through all the vertex normals
for (std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();++It,i++)
// and move each mesh point in the normal direction
_kernel.MovePoint(i,It->Normalize() * fSize);
_kernel.RecalcBoundBox();
}
void MeshObject::offsetSpecial2(float fSize)
{
Base::Builder3D builder;
std::vector<Base::Vector3f> PointNormals= _kernel.CalcVertexNormals();
std::vector<Base::Vector3f> FaceNormals;
std::set<unsigned long> fliped;
MeshCore::MeshFacetIterator it(_kernel);
for (it.Init(); it.More(); it.Next())
FaceNormals.push_back(it->GetNormal().Normalize());
unsigned int i = 0;
// go through all the vertex normals
for (std::vector<Base::Vector3f>::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++){
builder.addSingleLine(_kernel.GetPoint(i),_kernel.GetPoint(i)+It->Normalize() * fSize);
// and move each mesh point in the normal direction
_kernel.MovePoint(i,It->Normalize() * fSize);
}
_kernel.RecalcBoundBox();
MeshCore::MeshTopoAlgorithm alg(_kernel);
for (int l= 0; l<1 ;l++) {
for ( it.Init(),i=0; it.More(); it.Next(),i++) {
if (it->IsFlag(MeshCore::MeshFacet::INVALID))
continue;
// calculate the angle between them
float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length()));
if (angle > 1.6) {
builder.addSinglePoint(it->GetGravityPoint(),4,1,0,0);
fliped.insert(it.Position());
}
}
// if there no flipped triangels -> stop
//int f =fliped.size();
if (fliped.size() == 0)
break;
for( std::set<unsigned long>::iterator It= fliped.begin();It!=fliped.end();++It)
alg.CollapseFacet(*It);
fliped.clear();
}
alg.Cleanup();
// search for intersected facets
MeshCore::MeshEvalSelfIntersection eval(_kernel);
std::vector<std::pair<unsigned long, unsigned long> > faces;
eval.GetIntersections(faces);
builder.saveToLog();
}
void MeshObject::offsetSpecial(float fSize, float zmax, float zmin)
{
std::vector<Base::Vector3f> normals = _kernel.CalcVertexNormals();
unsigned int i = 0;
// go through all the vertex normals
for (std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();++It,i++) {
Base::Vector3f Pnt = _kernel.GetPoint(i);
if (Pnt.z < zmax && Pnt.z > zmin) {
Pnt.z = 0;
_kernel.MovePoint(i,Pnt.Normalize() * fSize);
}
else {
// and move each mesh point in the normal direction
_kernel.MovePoint(i,It->Normalize() * fSize);
}
}
}
void MeshObject::clear(void)
{
_kernel.Clear();
this->_segments.clear();
setTransform(Base::Matrix4D());
}
void MeshObject::transformToEigenSystem()
{
MeshCore::MeshEigensystem cMeshEval(_kernel);
cMeshEval.Evaluate();
this->setTransform(cMeshEval.Transform());
}
Base::Matrix4D MeshObject::getEigenSystem(Base::Vector3d& v) const
{
MeshCore::MeshEigensystem cMeshEval(_kernel);
cMeshEval.Evaluate();
Base::Vector3f uvw = cMeshEval.GetBoundings();
v.Set(uvw.x, uvw.y, uvw.z);
return cMeshEval.Transform();
}
void MeshObject::movePoint(unsigned long index, const Base::Vector3d& v)
{
// v is a vector, hence we must not apply the translation part
// of the transformation to the vector
Base::Vector3d vec(v);
vec.x += _Mtrx[0][3];
vec.y += _Mtrx[1][3];
vec.z += _Mtrx[2][3];
_kernel.MovePoint(index,transformToInside(vec));
}
void MeshObject::setPoint(unsigned long index, const Base::Vector3d& p)
{
_kernel.SetPoint(index,transformToInside(p));
}
void MeshObject::smooth(int iterations, float d_max)
{
_kernel.Smooth(iterations, d_max);
}
Base::Vector3d MeshObject::getPointNormal(unsigned long index) const
{
std::vector<Base::Vector3f> temp = _kernel.CalcVertexNormals();
Base::Vector3d normal = transformToOutside(temp[index]);
// the normal is a vector, hence we must not apply the translation part
// of the transformation to the vector
normal.x -= _Mtrx[0][3];
normal.y -= _Mtrx[1][3];
normal.z -= _Mtrx[2][3];
normal.Normalize();
return normal;
}
std::vector<Base::Vector3d> MeshObject::getPointNormals() const
{
std::vector<Base::Vector3f> temp = _kernel.CalcVertexNormals();
std::vector<Base::Vector3d> normals;
normals.reserve(temp.size());
for (std::vector<Base::Vector3f>::iterator it = temp.begin(); it != temp.end(); ++it) {
Base::Vector3d normal = transformToOutside(*it);
// the normal is a vector, hence we must not apply the translation part
// of the transformation to the vector
normal.x -= _Mtrx[0][3];
normal.y -= _Mtrx[1][3];
normal.z -= _Mtrx[2][3];
normal.Normalize();
normals.push_back(normal);
}
return normals;
}
void MeshObject::crossSections(const std::vector<MeshObject::TPlane>& planes, std::vector<MeshObject::TPolylines> &sections,
float fMinEps, bool bConnectPolygons) const
{
MeshCore::MeshFacetGrid grid(_kernel);
MeshCore::MeshAlgorithm algo(_kernel);
for (std::vector<MeshObject::TPlane>::const_iterator it = planes.begin(); it != planes.end(); ++it) {
MeshObject::TPolylines polylines;
algo.CutWithPlane(it->first, it->second, grid, polylines, fMinEps, bConnectPolygons);
sections.push_back(polylines);
}
}
void MeshObject::cut(const Base::Polygon2D& polygon2d,
const Base::ViewProjMethod& proj, MeshObject::CutType type)
{
MeshCore::MeshAlgorithm meshAlg(this->_kernel);
std::vector<unsigned long> check;
bool inner;
switch (type) {
case INNER:
inner = true;
break;
case OUTER:
inner = false;
break;
default:
inner = true;
break;
}
MeshCore::MeshFacetGrid meshGrid(this->_kernel);
meshAlg.CheckFacets(meshGrid, &proj, polygon2d, inner, check);
if (!check.empty())
this->deleteFacets(check);
}
void MeshObject::trim(const Base::Polygon2D& polygon2d,
const Base::ViewProjMethod& proj, MeshObject::CutType type)
{
MeshCore::MeshTrimming trim(this->_kernel, &proj, polygon2d);
std::vector<unsigned long> check;
std::vector<MeshCore::MeshGeomFacet> triangle;
switch (type) {
case INNER:
trim.SetInnerOrOuter(MeshCore::MeshTrimming::INNER);
break;
case OUTER:
trim.SetInnerOrOuter(MeshCore::MeshTrimming::OUTER);
break;
}
MeshCore::MeshFacetGrid meshGrid(this->_kernel);
trim.CheckFacets(meshGrid, check);
trim.TrimFacets(check, triangle);
if (!check.empty())
this->deleteFacets(check);
if (!triangle.empty())
this->_kernel.AddFacets(triangle);
}
MeshObject* MeshObject::unite(const MeshObject& mesh) const
{
MeshCore::MeshKernel result;
MeshCore::MeshKernel kernel1(this->_kernel);
kernel1.Transform(this->_Mtrx);
MeshCore::MeshKernel kernel2(mesh._kernel);
kernel2.Transform(mesh._Mtrx);
MeshCore::SetOperations setOp(kernel1, kernel2, result,
MeshCore::SetOperations::Union, Epsilon);
setOp.Do();
return new MeshObject(result);
}
MeshObject* MeshObject::intersect(const MeshObject& mesh) const
{
MeshCore::MeshKernel result;
MeshCore::MeshKernel kernel1(this->_kernel);
kernel1.Transform(this->_Mtrx);
MeshCore::MeshKernel kernel2(mesh._kernel);
kernel2.Transform(mesh._Mtrx);
MeshCore::SetOperations setOp(kernel1, kernel2, result,
MeshCore::SetOperations::Intersect, Epsilon);
setOp.Do();
return new MeshObject(result);
}
MeshObject* MeshObject::subtract(const MeshObject& mesh) const
{
MeshCore::MeshKernel result;
MeshCore::MeshKernel kernel1(this->_kernel);
kernel1.Transform(this->_Mtrx);
MeshCore::MeshKernel kernel2(mesh._kernel);
kernel2.Transform(mesh._Mtrx);
MeshCore::SetOperations setOp(kernel1, kernel2, result,
MeshCore::SetOperations::Difference, Epsilon);
setOp.Do();
return new MeshObject(result);
}
MeshObject* MeshObject::inner(const MeshObject& mesh) const
{
MeshCore::MeshKernel result;
MeshCore::MeshKernel kernel1(this->_kernel);
kernel1.Transform(this->_Mtrx);
MeshCore::MeshKernel kernel2(mesh._kernel);
kernel2.Transform(mesh._Mtrx);
MeshCore::SetOperations setOp(kernel1, kernel2, result,
MeshCore::SetOperations::Inner, Epsilon);
setOp.Do();
return new MeshObject(result);
}
MeshObject* MeshObject::outer(const MeshObject& mesh) const
{
MeshCore::MeshKernel result;
MeshCore::MeshKernel kernel1(this->_kernel);
kernel1.Transform(this->_Mtrx);
MeshCore::MeshKernel kernel2(mesh._kernel);
kernel2.Transform(mesh._Mtrx);
MeshCore::SetOperations setOp(kernel1, kernel2, result,
MeshCore::SetOperations::Outer, Epsilon);
setOp.Do();
return new MeshObject(result);
}
void MeshObject::refine()
{
unsigned long cnt = _kernel.CountFacets();
MeshCore::MeshFacetIterator cF(_kernel);
MeshCore::MeshTopoAlgorithm topalg(_kernel);
for (unsigned long i=0; i<cnt; i++) {
cF.Set(i);
if (!cF->IsDeformed())
topalg.InsertVertexAndSwapEdge(i, cF->GetGravityPoint(), 0.1f);
}
// clear the segments because we don't know how the new
// topology looks like
this->_segments.clear();
}
void MeshObject::optimizeTopology(float fMaxAngle)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
if (fMaxAngle > 0.0f)
topalg.OptimizeTopology(fMaxAngle);
else
topalg.OptimizeTopology();
// clear the segments because we don't know how the new
// topology looks like
this->_segments.clear();
}
void MeshObject::optimizeEdges()
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.AdjustEdgesToCurvatureDirection();
}
void MeshObject::splitEdges()
{
std::vector<std::pair<unsigned long, unsigned long> > adjacentFacet;
MeshCore::MeshAlgorithm alg(_kernel);
alg.ResetFacetFlag(MeshCore::MeshFacet::VISIT);
const MeshCore::MeshFacetArray& rFacets = _kernel.GetFacets();
for (MeshCore::MeshFacetArray::_TConstIterator pF = rFacets.begin(); pF != rFacets.end(); ++pF) {
int id=2;
if (pF->_aulNeighbours[id] != ULONG_MAX) {
const MeshCore::MeshFacet& rFace = rFacets[pF->_aulNeighbours[id]];
if (!pF->IsFlag(MeshCore::MeshFacet::VISIT) && !rFace.IsFlag(MeshCore::MeshFacet::VISIT)) {
pF->SetFlag(MeshCore::MeshFacet::VISIT);
rFace.SetFlag(MeshCore::MeshFacet::VISIT);
adjacentFacet.push_back(std::make_pair(pF-rFacets.begin(), pF->_aulNeighbours[id]));
}
}
}
MeshCore::MeshFacetIterator cIter(_kernel);
MeshCore::MeshTopoAlgorithm topalg(_kernel);
for (std::vector<std::pair<unsigned long, unsigned long> >::iterator it = adjacentFacet.begin(); it != adjacentFacet.end(); ++it) {
cIter.Set(it->first);
Base::Vector3f mid = 0.5f*(cIter->_aclPoints[0]+cIter->_aclPoints[2]);
topalg.SplitEdge(it->first, it->second, mid);
}
// clear the segments because we don't know how the new
// topology looks like
this->_segments.clear();
}
void MeshObject::splitEdge(unsigned long facet, unsigned long neighbour, const Base::Vector3f& v)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.SplitEdge(facet, neighbour, v);
}
void MeshObject::splitFacet(unsigned long facet, const Base::Vector3f& v1, const Base::Vector3f& v2)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.SplitFacet(facet, v1, v2);
}
void MeshObject::swapEdge(unsigned long facet, unsigned long neighbour)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.SwapEdge(facet, neighbour);
}
void MeshObject::collapseEdge(unsigned long facet, unsigned long neighbour)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.CollapseEdge(facet, neighbour);
std::vector<unsigned long> remFacets;
remFacets.push_back(facet);
remFacets.push_back(neighbour);
deletedFacets(remFacets);
}
void MeshObject::collapseFacet(unsigned long facet)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.CollapseFacet(facet);
std::vector<unsigned long> remFacets;
remFacets.push_back(facet);
deletedFacets(remFacets);
}
void MeshObject::collapseFacets(const std::vector<unsigned long>& facets)
{
MeshCore::MeshTopoAlgorithm alg(_kernel);
for (std::vector<unsigned long>::const_iterator it = facets.begin(); it != facets.end(); ++it) {
alg.CollapseFacet(*it);
}
deletedFacets(facets);
}
void MeshObject::insertVertex(unsigned long facet, const Base::Vector3f& v)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.InsertVertex(facet, v);
}
void MeshObject::snapVertex(unsigned long facet, const Base::Vector3f& v)
{
MeshCore::MeshTopoAlgorithm topalg(_kernel);
topalg.SnapVertex(facet, v);
}
unsigned long MeshObject::countNonUniformOrientedFacets() const
{
MeshCore::MeshEvalOrientation cMeshEval(_kernel);
std::vector<unsigned long> inds = cMeshEval.GetIndices();
return inds.size();
}
void MeshObject::flipNormals()
{
MeshCore::MeshTopoAlgorithm alg(_kernel);
alg.FlipNormals();
}
void MeshObject::harmonizeNormals()
{
MeshCore::MeshTopoAlgorithm alg(_kernel);
alg.HarmonizeNormals();
}
bool MeshObject::hasNonManifolds() const
{
MeshCore::MeshEvalTopology cMeshEval(_kernel);
return !cMeshEval.Evaluate();
}
void MeshObject::removeNonManifolds()
{
MeshCore::MeshEvalTopology f_eval(_kernel);
if (!f_eval.Evaluate()) {
MeshCore::MeshFixTopology f_fix(_kernel, f_eval.GetFacets());
f_fix.Fixup();
deletedFacets(f_fix.GetDeletedFaces());
}
}
void MeshObject::removeNonManifoldPoints()
{
MeshCore::MeshEvalPointManifolds p_eval(_kernel);
if (!p_eval.Evaluate()) {
std::vector<unsigned long> faces;
p_eval.GetFacetIndices(faces);
deleteFacets(faces);
}
}
bool MeshObject::hasSelfIntersections() const
{
MeshCore::MeshEvalSelfIntersection cMeshEval(_kernel);
return !cMeshEval.Evaluate();
}
void MeshObject::removeSelfIntersections()
{
std::vector<std::pair<unsigned long, unsigned long> > selfIntersections;
MeshCore::MeshEvalSelfIntersection cMeshEval(_kernel);
cMeshEval.GetIntersections(selfIntersections);
if (!selfIntersections.empty()) {
MeshCore::MeshFixSelfIntersection cMeshFix(_kernel, selfIntersections);
deleteFacets(cMeshFix.GetFacets());
}
}
void MeshObject::removeSelfIntersections(const std::vector<unsigned long>& indices)
{
// make sure that the number of indices is even and are in range
if (indices.size() % 2 != 0)
return;
if (std::find_if(indices.begin(), indices.end(),
std::bind2nd(std::greater_equal<unsigned long>(), _kernel.CountFacets())) < indices.end())
return;
std::vector<std::pair<unsigned long, unsigned long> > selfIntersections;
std::vector<unsigned long>::const_iterator it;
for (it = indices.begin(); it != indices.end(); ) {
unsigned long id1 = *it; ++it;
unsigned long id2 = *it; ++it;
selfIntersections.push_back(std::make_pair(id1,id2));
}
if (!selfIntersections.empty()) {
MeshCore::MeshFixSelfIntersection cMeshFix(_kernel, selfIntersections);
cMeshFix.Fixup();
this->_segments.clear();
}
}
void MeshObject::removeFoldsOnSurface()
{
std::vector<unsigned long> indices;
MeshCore::MeshEvalFoldsOnSurface s_eval(_kernel);
MeshCore::MeshEvalFoldOversOnSurface f_eval(_kernel);
f_eval.Evaluate();
std::vector<unsigned long> inds = f_eval.GetIndices();
s_eval.Evaluate();
std::vector<unsigned long> inds1 = s_eval.GetIndices();
// remove duplicates
inds.insert(inds.end(), inds1.begin(), inds1.end());
std::sort(inds.begin(), inds.end());
inds.erase(std::unique(inds.begin(), inds.end()), inds.end());
if (!inds.empty())
deleteFacets(inds);
// do this as additional check after removing folds on closed area
for (int i=0; i<5; i++) {
MeshCore::MeshEvalFoldsOnBoundary b_eval(_kernel);
if (b_eval.Evaluate())
break;
inds = b_eval.GetIndices();
if (!inds.empty())
deleteFacets(inds);
}
}
void MeshObject::removeFullBoundaryFacets()
{
std::vector<unsigned long> facets;
if (!MeshCore::MeshEvalBorderFacet(_kernel, facets).Evaluate()) {
deleteFacets(facets);
}
}
bool MeshObject::hasInvalidPoints() const
{
MeshCore::MeshEvalNaNPoints nan(_kernel);
return !nan.GetIndices().empty();
}
void MeshObject::removeInvalidPoints()
{
MeshCore::MeshEvalNaNPoints nan(_kernel);
deletePoints(nan.GetIndices());
}
void MeshObject::validateIndices()
{
unsigned long count = _kernel.CountFacets();
// for invalid neighbour indices we don't need to check first
// but start directly with the validation
MeshCore::MeshFixNeighbourhood fix(_kernel);
fix.Fixup();
MeshCore::MeshEvalRangeFacet rf(_kernel);
if (!rf.Evaluate()) {
MeshCore::MeshFixRangeFacet fix(_kernel);
fix.Fixup();
}
MeshCore::MeshEvalRangePoint rp(_kernel);
if (!rp.Evaluate()) {
MeshCore::MeshFixRangePoint fix(_kernel);
fix.Fixup();
}
MeshCore::MeshEvalCorruptedFacets cf(_kernel);
if (!cf.Evaluate()) {
MeshCore::MeshFixCorruptedFacets fix(_kernel);
fix.Fixup();
}
if (_kernel.CountFacets() < count)
this->_segments.clear();
}
void MeshObject::validateDeformations(float fMaxAngle, float fEps)
{
unsigned long count = _kernel.CountFacets();
MeshCore::MeshFixDeformedFacets eval(_kernel, fMaxAngle, fEps);
eval.Fixup();
if (_kernel.CountFacets() < count)
this->_segments.clear();
}
void MeshObject::validateDegenerations(float fEps)
{
unsigned long count = _kernel.CountFacets();
MeshCore::MeshFixDegeneratedFacets eval(_kernel, fEps);
eval.Fixup();
if (_kernel.CountFacets() < count)
this->_segments.clear();
}
void MeshObject::removeDuplicatedPoints()
{
unsigned long count = _kernel.CountFacets();
MeshCore::MeshFixDuplicatePoints eval(_kernel);
eval.Fixup();
if (_kernel.CountFacets() < count)
this->_segments.clear();
}
void MeshObject::removeDuplicatedFacets()
{
unsigned long count = _kernel.CountFacets();
MeshCore::MeshFixDuplicateFacets eval(_kernel);
eval.Fixup();
if (_kernel.CountFacets() < count)
this->_segments.clear();
}
MeshObject* MeshObject::createMeshFromList(Py::List& list)
{
std::vector<MeshCore::MeshGeomFacet> facets;
MeshCore::MeshGeomFacet facet;
int i = 0;
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
Py::List item(*it);
for (int j = 0; j < 3; j++) {
Py::Float value(item[j]);
facet._aclPoints[i][j] = (float)value;
}
if (++i == 3) {
i = 0;
facet.CalcNormal();
facets.push_back(facet);
}
}
Base::EmptySequencer seq;
std::auto_ptr<MeshObject> mesh(new MeshObject);
//mesh->addFacets(facets);
mesh->getKernel() = facets;
return mesh.release();
}
MeshObject* MeshObject::createSphere(float radius, int sampling)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Sphere"));
Py::Tuple args(2);
args.setItem(0, Py::Float(radius));
args.setItem(1, Py::Int(sampling));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createEllipsoid(float radius1, float radius2, int sampling)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Ellipsoid"));
Py::Tuple args(3);
args.setItem(0, Py::Float(radius1));
args.setItem(1, Py::Float(radius2));
args.setItem(2, Py::Int(sampling));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createCylinder(float radius, float length, int closed, float edgelen, int sampling)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Cylinder"));
Py::Tuple args(5);
args.setItem(0, Py::Float(radius));
args.setItem(1, Py::Float(length));
args.setItem(2, Py::Int(closed));
args.setItem(3, Py::Float(edgelen));
args.setItem(4, Py::Int(sampling));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createCone(float radius1, float radius2, float len, int closed, float edgelen, int sampling)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Cone"));
Py::Tuple args(6);
args.setItem(0, Py::Float(radius1));
args.setItem(1, Py::Float(radius2));
args.setItem(2, Py::Float(len));
args.setItem(3, Py::Int(closed));
args.setItem(4, Py::Float(edgelen));
args.setItem(5, Py::Int(sampling));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createTorus(float radius1, float radius2, int sampling)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Toroid"));
Py::Tuple args(3);
args.setItem(0, Py::Float(radius1));
args.setItem(1, Py::Float(radius2));
args.setItem(2, Py::Int(sampling));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createCube(float length, float width, float height)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("Cube"));
Py::Tuple args(3);
args.setItem(0, Py::Float(length));
args.setItem(1, Py::Float(width));
args.setItem(2, Py::Float(height));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
MeshObject* MeshObject::createCube(float length, float width, float height, float edgelen)
{
// load the 'BuildRegularGeoms' module
Base::PyGILStateLocker lock;
try {
Py::Module module(PyImport_ImportModule("BuildRegularGeoms"),true);
Py::Dict dict = module.getDict();
Py::Callable call(dict.getItem("FineCube"));
Py::Tuple args(4);
args.setItem(0, Py::Float(length));
args.setItem(1, Py::Float(width));
args.setItem(2, Py::Float(height));
args.setItem(3, Py::Float(edgelen));
Py::List list(call.apply(args));
return createMeshFromList(list);
}
catch (Py::Exception& e) {
e.clear();
}
return 0;
}
void MeshObject::addSegment(const Segment& s)
{
addSegment(s.getIndices());
this->_segments.back().setName(s.getName());
this->_segments.back().save(s.isSaved());
}
void MeshObject::addSegment(const std::vector<unsigned long>& inds)
{
unsigned long maxIndex = _kernel.CountFacets();
for (std::vector<unsigned long>::const_iterator it = inds.begin(); it != inds.end(); ++it) {
if (*it >= maxIndex)
throw Base::Exception("Index out of range");
}
this->_segments.push_back(Segment(this,inds,true));
}
const Segment& MeshObject::getSegment(unsigned long index) const
{
return this->_segments[index];
}
Segment& MeshObject::getSegment(unsigned long index)
{
return this->_segments[index];
}
MeshObject* MeshObject::meshFromSegment(const std::vector<unsigned long>& indices) const
{
MeshCore::MeshFacetArray facets;
facets.reserve(indices.size());
const MeshCore::MeshPointArray& kernel_p = _kernel.GetPoints();
const MeshCore::MeshFacetArray& kernel_f = _kernel.GetFacets();
for (std::vector<unsigned long>::const_iterator it = indices.begin(); it != indices.end(); ++it) {
facets.push_back(kernel_f[*it]);
}
MeshCore::MeshKernel kernel;
kernel.Merge(kernel_p, facets);
return new MeshObject(kernel, _Mtrx);
}
std::vector<Segment> MeshObject::getSegmentsFromType(MeshObject::GeometryType type, const Segment& aSegment,
float dev, unsigned long minFacets) const
{
std::vector<Segment> segm;
if (this->_kernel.CountFacets() == 0)
return segm;
MeshCore::MeshSegmentAlgorithm finder(this->_kernel);
MeshCore::MeshDistanceSurfaceSegment* surf;
surf = new MeshCore::MeshDistancePlanarSegment(this->_kernel, minFacets, dev);
std::vector<MeshCore::MeshSurfaceSegment*> surfaces;
surfaces.push_back(surf);
finder.FindSegments(surfaces);
const std::vector<MeshCore::MeshSegment>& data = surf->GetSegments();
for (std::vector<MeshCore::MeshSegment>::const_iterator it = data.begin(); it != data.end(); ++it) {
segm.push_back(Segment(const_cast<MeshObject*>(this), *it, false));
}
delete surf;
return segm;
}
// ----------------------------------------------------------------------------
MeshObject::const_point_iterator::const_point_iterator(const MeshObject* mesh, unsigned long index)
: _mesh(mesh), _p_it(mesh->getKernel())
{
this->_p_it.Set(index);
this->_p_it.Transform(_mesh->_Mtrx);
this->_point.Mesh = const_cast<MeshObject*>(_mesh);
}
MeshObject::const_point_iterator::const_point_iterator(const MeshObject::const_point_iterator& fi)
: _mesh(fi._mesh), _point(fi._point), _p_it(fi._p_it)
{
}
MeshObject::const_point_iterator::~const_point_iterator()
{
}
MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator=(const MeshObject::const_point_iterator& pi)
{
this->_mesh = pi._mesh;
this->_point = pi._point;
this->_p_it = pi._p_it;
return *this;
}
void MeshObject::const_point_iterator::dereference()
{
this->_point.x = _p_it->x;
this->_point.y = _p_it->y;
this->_point.z = _p_it->z;
this->_point.Index = _p_it.Position();
}
const MeshPoint& MeshObject::const_point_iterator::operator*()
{
dereference();
return this->_point;
}
const MeshPoint* MeshObject::const_point_iterator::operator->()
{
dereference();
return &(this->_point);
}
bool MeshObject::const_point_iterator::operator==(const MeshObject::const_point_iterator& pi) const
{
return (this->_mesh == pi._mesh) && (this->_p_it == pi._p_it);
}
bool MeshObject::const_point_iterator::operator!=(const MeshObject::const_point_iterator& pi) const
{
return !operator==(pi);
}
MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator++()
{
++(this->_p_it);
return *this;
}
MeshObject::const_point_iterator& MeshObject::const_point_iterator::operator--()
{
--(this->_p_it);
return *this;
}
// ----------------------------------------------------------------------------
MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject* mesh, unsigned long index)
: _mesh(mesh), _f_it(mesh->getKernel())
{
this->_f_it.Set(index);
this->_f_it.Transform(_mesh->_Mtrx);
this->_facet.Mesh = const_cast<MeshObject*>(_mesh);
}
MeshObject::const_facet_iterator::const_facet_iterator(const MeshObject::const_facet_iterator& fi)
: _mesh(fi._mesh), _facet(fi._facet), _f_it(fi._f_it)
{
}
MeshObject::const_facet_iterator::~const_facet_iterator()
{
}
MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator=(const MeshObject::const_facet_iterator& fi)
{
this->_mesh = fi._mesh;
this->_facet = fi._facet;
this->_f_it = fi._f_it;
return *this;
}
void MeshObject::const_facet_iterator::dereference()
{
this->_facet.MeshCore::MeshGeomFacet::operator = (*_f_it);
this->_facet.Index = _f_it.Position();
const MeshCore::MeshFacet& face = _f_it.GetReference();
for (int i=0; i<3;i++) {
this->_facet.PIndex[i] = face._aulPoints[i];
this->_facet.NIndex[i] = face._aulNeighbours[i];
}
}
Facet& MeshObject::const_facet_iterator::operator*()
{
dereference();
return this->_facet;
}
Facet* MeshObject::const_facet_iterator::operator->()
{
dereference();
return &(this->_facet);
}
bool MeshObject::const_facet_iterator::operator==(const MeshObject::const_facet_iterator& fi) const
{
return (this->_mesh == fi._mesh) && (this->_f_it == fi._f_it);
}
bool MeshObject::const_facet_iterator::operator!=(const MeshObject::const_facet_iterator& fi) const
{
return !operator==(fi);
}
MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator++()
{
++(this->_f_it);
return *this;
}
MeshObject::const_facet_iterator& MeshObject::const_facet_iterator::operator--()
{
--(this->_f_it);
return *this;
}