MeshProperties.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 #endif
00027
00028 #include <CXX/Objects.hxx>
00029 #include <Base/Console.h>
00030 #include <Base/Exception.h>
00031 #include <Base/Writer.h>
00032 #include <Base/Reader.h>
00033 #include <Base/Stream.h>
00034
00035 #include "Core/MeshKernel.h"
00036 #include "Core/MeshIO.h"
00037 #include "Core/Iterator.h"
00038
00039 #include "MeshProperties.h"
00040 #include "Mesh.h"
00041 #include "MeshPy.h"
00042
00043 using namespace Mesh;
00044
00045 TYPESYSTEM_SOURCE(Mesh::PropertyNormalList, App::PropertyVectorList);
00046 TYPESYSTEM_SOURCE(Mesh::PropertyCurvatureList , App::PropertyLists);
00047 TYPESYSTEM_SOURCE(Mesh::PropertyMeshKernel , App::PropertyComplexGeoData);
00048
00049 void PropertyNormalList::transform(const Base::Matrix4D &mat)
00050 {
00051
00052
00053
00054
00055
00056
00057 double s[3];
00058 s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
00059 s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
00060 s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
00061
00062
00063 Base::Matrix4D rot;
00064 rot.setToUnity();
00065 for (unsigned short i = 0; i < 3; i++) {
00066 for (unsigned short j = 0; j < 3; j++) {
00067 rot[i][j] = mat[i][j] / s[i];
00068 }
00069 }
00070
00071 aboutToSetValue();
00072
00073
00074 for (int ii=0; ii<getSize(); ii++) {
00075 set1Value(ii, rot * operator[](ii));
00076 }
00077
00078 hasSetValue();
00079
00080 }
00081
00082
00083
00084 PropertyCurvatureList::PropertyCurvatureList()
00085 {
00086
00087 }
00088
00089 PropertyCurvatureList::~PropertyCurvatureList()
00090 {
00091
00092 }
00093
00094 void PropertyCurvatureList::setValue(const CurvatureInfo& lValue)
00095 {
00096 aboutToSetValue();
00097 _lValueList.resize(1);
00098 _lValueList[0]=lValue;
00099 hasSetValue();
00100 }
00101
00102 void PropertyCurvatureList::setValues(const std::vector<CurvatureInfo>& lValues)
00103 {
00104 aboutToSetValue();
00105 _lValueList=lValues;
00106 hasSetValue();
00107 }
00108
00109 std::vector<float> PropertyCurvatureList::getCurvature( int mode ) const
00110 {
00111 const std::vector<Mesh::CurvatureInfo>& fCurvInfo = getValues();
00112 std::vector<float> fValues;
00113 fValues.reserve(fCurvInfo.size());
00114
00115
00116 if (mode == MeanCurvature) {
00117 for ( std::vector<Mesh::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it )
00118 {
00119 fValues.push_back( 0.5f*(it->fMaxCurvature+it->fMinCurvature) );
00120 }
00121 }
00122
00123 else if (mode == GaussCurvature) {
00124 for ( std::vector<Mesh::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it )
00125 {
00126 fValues.push_back( it->fMaxCurvature * it->fMinCurvature );
00127 }
00128 }
00129
00130 else if (mode == MaxCurvature) {
00131 for ( std::vector<Mesh::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it )
00132 {
00133 fValues.push_back( it->fMaxCurvature );
00134 }
00135 }
00136
00137 else if (mode == MinCurvature) {
00138 for ( std::vector<Mesh::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it )
00139 {
00140 fValues.push_back( it->fMinCurvature );
00141 }
00142 }
00143
00144 else if (mode == AbsCurvature) {
00145 for ( std::vector<Mesh::CurvatureInfo>::const_iterator it=fCurvInfo.begin();it!=fCurvInfo.end(); ++it )
00146 {
00147 if ( fabs(it->fMaxCurvature) > fabs(it->fMinCurvature) )
00148 fValues.push_back( it->fMaxCurvature );
00149 else
00150 fValues.push_back( it->fMinCurvature );
00151 }
00152 }
00153
00154 return fValues;
00155 }
00156
00157 void PropertyCurvatureList::transform(const Base::Matrix4D &mat)
00158 {
00159
00160
00161
00162
00163
00164
00165 double s[3];
00166 s[0] = sqrt(mat[0][0] * mat[0][0] + mat[0][1] * mat[0][1] + mat[0][2] * mat[0][2]);
00167 s[1] = sqrt(mat[1][0] * mat[1][0] + mat[1][1] * mat[1][1] + mat[1][2] * mat[1][2]);
00168 s[2] = sqrt(mat[2][0] * mat[2][0] + mat[2][1] * mat[2][1] + mat[2][2] * mat[2][2]);
00169
00170
00171 Base::Matrix4D rot;
00172 rot.setToUnity();
00173 for (unsigned short i = 0; i < 3; i++) {
00174 for (unsigned short j = 0; j < 3; j++) {
00175 rot[i][j] = mat[i][j] / s[i];
00176 }
00177 }
00178
00179 aboutToSetValue();
00180
00181
00182 for (int ii=0; ii<getSize(); ii++)
00183 {
00184 CurvatureInfo ci = operator[](ii);
00185 ci.cMaxCurvDir = rot * ci.cMaxCurvDir;
00186 ci.cMinCurvDir = rot * ci.cMinCurvDir;
00187 _lValueList[ii] = ci;
00188 }
00189
00190 hasSetValue();
00191 }
00192
00193 void PropertyCurvatureList::Save (Base::Writer &writer) const
00194 {
00195 if (!writer.isForceXML()) {
00196 writer.Stream() << writer.ind() << "<CurvatureList file=\"" <<
00197 writer.addFile(getName(), this) << "\"/>" << std::endl;
00198 }
00199 }
00200
00201 void PropertyCurvatureList::Restore(Base::XMLReader &reader)
00202 {
00203 reader.readElement("CurvatureList");
00204 std::string file (reader.getAttribute("file") );
00205
00206 if (!file.empty()) {
00207
00208 reader.addFile(file.c_str(),this);
00209 }
00210 }
00211
00212 void PropertyCurvatureList::SaveDocFile (Base::Writer &writer) const
00213 {
00214 Base::OutputStream str(writer.Stream());
00215 uint32_t uCt = (uint32_t)getSize();
00216 str << uCt;
00217 for (std::vector<CurvatureInfo>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
00218 str << it->fMaxCurvature << it->fMinCurvature;
00219 str << it->cMaxCurvDir.x << it->cMaxCurvDir.y << it->cMaxCurvDir.z;
00220 str << it->cMinCurvDir.x << it->cMinCurvDir.y << it->cMinCurvDir.z;
00221 }
00222 }
00223
00224 void PropertyCurvatureList::RestoreDocFile(Base::Reader &reader)
00225 {
00226 Base::InputStream str(reader);
00227 uint32_t uCt=0;
00228 str >> uCt;
00229 std::vector<CurvatureInfo> values(uCt);
00230 for (std::vector<CurvatureInfo>::iterator it = values.begin(); it != values.end(); ++it) {
00231 str >> it->fMaxCurvature >> it->fMinCurvature;
00232 str >> it->cMaxCurvDir.x >> it->cMaxCurvDir.y >> it->cMaxCurvDir.z;
00233 str >> it->cMinCurvDir.x >> it->cMinCurvDir.y >> it->cMinCurvDir.z;
00234 }
00235
00236 setValues(values);
00237 }
00238
00239 PyObject* PropertyCurvatureList::getPyObject(void)
00240 {
00241 Py::List list;
00242 for (std::vector<CurvatureInfo>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
00243 Py::Tuple tuple(4);
00244 tuple.setItem(0, Py::Float(it->fMaxCurvature));
00245 tuple.setItem(1, Py::Float(it->fMinCurvature));
00246 Py::Tuple maxDir(3);
00247 maxDir.setItem(0, Py::Float(it->cMaxCurvDir.x));
00248 maxDir.setItem(1, Py::Float(it->cMaxCurvDir.y));
00249 maxDir.setItem(2, Py::Float(it->cMaxCurvDir.z));
00250 tuple.setItem(2, maxDir);
00251 Py::Tuple minDir(3);
00252 minDir.setItem(0, Py::Float(it->cMinCurvDir.x));
00253 minDir.setItem(1, Py::Float(it->cMinCurvDir.y));
00254 minDir.setItem(2, Py::Float(it->cMinCurvDir.z));
00255 tuple.setItem(3, minDir);
00256 list.append(tuple);
00257 }
00258
00259 return Py::new_reference_to(list);
00260 }
00261
00262 void PropertyCurvatureList::setPyObject(PyObject *value)
00263 {
00264 throw Py::AttributeError(std::string("This attribute is read-only"));
00265 }
00266
00267 App::Property *PropertyCurvatureList::Copy(void) const
00268 {
00269 PropertyCurvatureList *p= new PropertyCurvatureList();
00270 p->_lValueList = _lValueList;
00271 return p;
00272 }
00273
00274 void PropertyCurvatureList::Paste(const App::Property &from)
00275 {
00276 aboutToSetValue();
00277 _lValueList = dynamic_cast<const PropertyCurvatureList&>(from)._lValueList;
00278 hasSetValue();
00279 }
00280
00281
00282
00283 PropertyMeshKernel::PropertyMeshKernel()
00284 : _meshObject(new MeshObject()), meshPyObject(0)
00285 {
00286
00287
00288
00289
00290 }
00291
00292 PropertyMeshKernel::~PropertyMeshKernel()
00293 {
00294 if (meshPyObject) {
00295
00296
00297 meshPyObject->parentProperty = 0;
00298 Py_DECREF(meshPyObject);
00299 }
00300 }
00301
00302 void PropertyMeshKernel::setValuePtr(MeshObject* mesh)
00303 {
00304
00305
00306 Base::Reference<MeshObject> tmp(_meshObject);
00307 aboutToSetValue();
00308 _meshObject = mesh;
00309 hasSetValue();
00310 }
00311
00312 void PropertyMeshKernel::setValue(const MeshObject& mesh)
00313 {
00314 aboutToSetValue();
00315 *_meshObject = mesh;
00316 hasSetValue();
00317 }
00318
00319 void PropertyMeshKernel::setValue(const MeshCore::MeshKernel& mesh)
00320 {
00321 aboutToSetValue();
00322 _meshObject->setKernel(mesh);
00323 hasSetValue();
00324 }
00325
00326 void PropertyMeshKernel::swapMesh(MeshObject& mesh)
00327 {
00328 aboutToSetValue();
00329 _meshObject->swap(mesh);
00330 hasSetValue();
00331 }
00332
00333 void PropertyMeshKernel::swapMesh(MeshCore::MeshKernel& mesh)
00334 {
00335 aboutToSetValue();
00336 _meshObject->swap(mesh);
00337 hasSetValue();
00338 }
00339
00340 const MeshObject& PropertyMeshKernel::getValue(void)const
00341 {
00342 return *_meshObject;
00343 }
00344
00345 const MeshObject* PropertyMeshKernel::getValuePtr(void)const
00346 {
00347 return (MeshObject*)_meshObject;
00348 }
00349
00350 const Data::ComplexGeoData* PropertyMeshKernel::getComplexData() const
00351 {
00352 return (MeshObject*)_meshObject;
00353 }
00354
00355 Base::BoundBox3d PropertyMeshKernel::getBoundingBox() const
00356 {
00357 return _meshObject->getBoundBox();
00358 }
00359
00360 void PropertyMeshKernel::getFaces(std::vector<Base::Vector3d> &aPoints,
00361 std::vector<Data::ComplexGeoData::Facet> &aTopo,
00362 float accuracy, uint16_t flags) const
00363 {
00364 _meshObject->getFaces(aPoints, aTopo, accuracy, flags);
00365 }
00366
00367 unsigned int PropertyMeshKernel::getMemSize (void) const
00368 {
00369 unsigned int size = 0;
00370 size += _meshObject->getMemSize();
00371
00372 return size;
00373 }
00374
00375 MeshObject* PropertyMeshKernel::startEditing()
00376 {
00377 aboutToSetValue();
00378 return (MeshObject*)_meshObject;
00379 }
00380
00381 void PropertyMeshKernel::finishEditing()
00382 {
00383 hasSetValue();
00384 }
00385
00386 void PropertyMeshKernel::transformGeometry(const Base::Matrix4D &rclMat)
00387 {
00388 aboutToSetValue();
00389 _meshObject->transformGeometry(rclMat);
00390 hasSetValue();
00391 }
00392
00393 void PropertyMeshKernel::deletePointIndices( const std::vector<unsigned long>& inds )
00394 {
00395 aboutToSetValue();
00396 _meshObject->deletePoints(inds);
00397 hasSetValue();
00398 }
00399
00400 void PropertyMeshKernel::deleteFacetIndices( const std::vector<unsigned long>& inds )
00401 {
00402 aboutToSetValue();
00403 _meshObject->deleteFacets(inds);
00404 hasSetValue();
00405 }
00406
00407 void PropertyMeshKernel::setPointIndices(const std::vector<std::pair<unsigned long, Base::Vector3f> >& inds)
00408 {
00409 aboutToSetValue();
00410 MeshCore::MeshKernel& kernel = _meshObject->getKernel();
00411 for (std::vector<std::pair<unsigned long, Base::Vector3f> >::const_iterator it = inds.begin(); it != inds.end(); ++it)
00412 kernel.SetPoint(it->first, it->second);
00413 hasSetValue();
00414 }
00415
00416 void PropertyMeshKernel::append(const std::vector<MeshCore::MeshFacet>& rFaces,
00417 const std::vector<Base::Vector3f>& rPoints)
00418 {
00419 aboutToSetValue();
00420 _meshObject->addFacets(rFaces, rPoints);
00421 hasSetValue();
00422 }
00423
00424 void PropertyMeshKernel::createSegment(const std::vector<unsigned long>& segm)
00425 {
00426 aboutToSetValue();
00427 _meshObject->addSegment(segm);
00428 hasSetValue();
00429 }
00430
00431 void PropertyMeshKernel::smooth(int iter, float d_max)
00432 {
00433 aboutToSetValue();
00434 _meshObject->smooth(iter, d_max);
00435 hasSetValue();
00436 }
00437
00438 void PropertyMeshKernel::clear()
00439 {
00440
00441 aboutToSetValue();
00442 _meshObject->clear();
00443 hasSetValue();
00444 }
00445
00446 void PropertyMeshKernel::harmonizeNormals()
00447 {
00448 aboutToSetValue();
00449 _meshObject->harmonizeNormals();
00450 hasSetValue();
00451 }
00452
00453 void PropertyMeshKernel::removeNonManifolds()
00454 {
00455 aboutToSetValue();
00456 _meshObject->removeNonManifolds();
00457 hasSetValue();
00458 }
00459
00460 void PropertyMeshKernel::validateIndices()
00461 {
00462 aboutToSetValue();
00463 _meshObject->validateIndices();
00464 hasSetValue();
00465 }
00466
00467 void PropertyMeshKernel::validateDegenerations()
00468 {
00469 aboutToSetValue();
00470 _meshObject->validateDegenerations();
00471 hasSetValue();
00472 }
00473
00474 void PropertyMeshKernel::validateDeformations(float fMaxAngle)
00475 {
00476 aboutToSetValue();
00477 _meshObject->validateDeformations(fMaxAngle);
00478 hasSetValue();
00479 }
00480
00481 void PropertyMeshKernel::removeDuplicatedFacets()
00482 {
00483 aboutToSetValue();
00484 _meshObject->removeDuplicatedFacets();
00485 hasSetValue();
00486 }
00487
00488 void PropertyMeshKernel::removeDuplicatedPoints()
00489 {
00490 aboutToSetValue();
00491 _meshObject->removeDuplicatedPoints();
00492 hasSetValue();
00493 }
00494
00495 void PropertyMeshKernel::removeSelfIntersections()
00496 {
00497 aboutToSetValue();
00498 _meshObject->removeSelfIntersections();
00499 hasSetValue();
00500 }
00501
00502 void PropertyMeshKernel::removeFoldsOnSurface()
00503 {
00504 aboutToSetValue();
00505 _meshObject->removeFoldsOnSurface();
00506 hasSetValue();
00507 }
00508
00509 PyObject *PropertyMeshKernel::getPyObject(void)
00510 {
00511 if (!meshPyObject) {
00512 meshPyObject = new MeshPy(&*_meshObject);
00513 meshPyObject->setConst();
00514 meshPyObject->parentProperty = this;
00515 }
00516
00517 Py_INCREF(meshPyObject);
00518 return meshPyObject;
00519 }
00520
00521 void PropertyMeshKernel::setPyObject(PyObject *value)
00522 {
00523 if (PyObject_TypeCheck(value, &(MeshPy::Type))) {
00524 MeshPy* mesh = static_cast<MeshPy*>(value);
00525
00526 if (&(*this->_meshObject) != mesh->getMeshObjectPtr()) {
00527
00528 setValue(*(mesh->getMeshObjectPtr()));
00529 }
00530 }
00531 else if (PyList_Check(value)) {
00532
00533 Py::List triangles(value);
00534 MeshObject* mesh = MeshObject::createMeshFromList(triangles);
00535 setValuePtr(mesh);
00536 }
00537 else {
00538 std::string error = std::string("type must be 'Mesh', not ");
00539 error += value->ob_type->tp_name;
00540 throw Py::TypeError(error);
00541 }
00542 }
00543
00544 void PropertyMeshKernel::Save (Base::Writer &writer) const
00545 {
00546 if (writer.isForceXML()) {
00547 writer.Stream() << writer.ind() << "<Mesh>" << std::endl;
00548 MeshCore::MeshOutput saver(_meshObject->getKernel());
00549 saver.SaveXML(writer);
00550 }
00551 else {
00552 writer.Stream() << writer.ind() << "<Mesh file=\"" <<
00553 writer.addFile("MeshKernel.bms", this) << "\"/>" << std::endl;
00554 }
00555 }
00556
00557 void PropertyMeshKernel::Restore(Base::XMLReader &reader)
00558 {
00559 reader.readElement("Mesh");
00560 std::string file (reader.getAttribute("file") );
00561
00562 if (file.empty()) {
00563
00564 MeshCore::MeshKernel kernel;
00565 MeshCore::MeshInput restorer(kernel);
00566 restorer.LoadXML(reader);
00567
00568
00569 MeshCore::MeshPointArray points;
00570 MeshCore::MeshFacetArray facets;
00571 kernel.Adopt(points, facets);
00572
00573 aboutToSetValue();
00574 _meshObject->getKernel().Adopt(points, facets);
00575 hasSetValue();
00576 }
00577 else {
00578
00579 reader.addFile(file.c_str(),this);
00580 }
00581 }
00582
00583 void PropertyMeshKernel::SaveDocFile (Base::Writer &writer) const
00584 {
00585 _meshObject->save(writer.Stream());
00586 }
00587
00588 void PropertyMeshKernel::RestoreDocFile(Base::Reader &reader)
00589 {
00590 aboutToSetValue();
00591 _meshObject->load(reader);
00592 hasSetValue();
00593 }
00594
00595 App::Property *PropertyMeshKernel::Copy(void) const
00596 {
00597
00598 PropertyMeshKernel *prop = new PropertyMeshKernel();
00599 *(prop->_meshObject) = *(this->_meshObject);
00600 return prop;
00601 }
00602
00603 void PropertyMeshKernel::Paste(const App::Property &from)
00604 {
00605
00606 aboutToSetValue();
00607 const PropertyMeshKernel& prop = dynamic_cast<const PropertyMeshKernel&>(from);
00608 *(this->_meshObject) = *(prop._meshObject);
00609 hasSetValue();
00610 }