From ec509f441f9a4f5d13d1029df7c78254eaee3b7a Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 17 Jan 2012 12:09:10 +0000 Subject: [PATCH 1/6] + ignore the 'Closable' flag in closeDocument() git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5413 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/App/Application.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 4a7d794071..aa49a55755 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -308,9 +308,6 @@ bool Application::closeDocument(const char* name) if (pos == DocMap.end()) // no such document return false; - if (!pos->second->isClosable()) - return false; - // Trigger observers before removing the document from the internal map. // Some observers might rely on that this document is still there. signalDeleteDocument(*pos->second); From c0986a76dca7359c44985beb23a857a869be658e Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 17 Jan 2012 15:08:47 +0000 Subject: [PATCH 2/6] + add method to get intersection of two curves git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5414 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/GeometryCurvePy.xml | 5 ++++ src/Mod/Part/App/GeometryCurvePyImp.cpp | 40 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/Mod/Part/App/GeometryCurvePy.xml b/src/Mod/Part/App/GeometryCurvePy.xml index 1b3b48e867..eaae3fb190 100644 --- a/src/Mod/Part/App/GeometryCurvePy.xml +++ b/src/Mod/Part/App/GeometryCurvePy.xml @@ -41,6 +41,11 @@ Make a ruled surface of this and the given curves + + + Get intersection points with another curve lying on a plane. + + Returns the parameter on the curve diff --git a/src/Mod/Part/App/GeometryCurvePyImp.cpp b/src/Mod/Part/App/GeometryCurvePyImp.cpp index 55d1a9a76d..2c9deb4e69 100644 --- a/src/Mod/Part/App/GeometryCurvePyImp.cpp +++ b/src/Mod/Part/App/GeometryCurvePyImp.cpp @@ -26,9 +26,13 @@ # include # include # include +# include # include +# include +# include # include # include +# include # include # include # include @@ -48,6 +52,7 @@ #include "GeometryCurvePy.cpp" #include "RectangularTrimmedSurfacePy.h" #include "BSplineSurfacePy.h" +#include "PlanePy.h" #include "TopoShape.h" #include "TopoShapePy.h" @@ -261,6 +266,41 @@ PyObject* GeometryCurvePy::makeRuledSurface(PyObject *args) return 0; } +PyObject* GeometryCurvePy::intersect2d(PyObject *args) +{ + PyObject *c,*p; + if (!PyArg_ParseTuple(args, "O!O!", &(Part::GeometryCurvePy::Type), &c, + &(Part::PlanePy::Type), &p)) + return 0; + + try { + Handle_Geom_Curve self = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle()); + Handle_Geom_Curve curv = Handle_Geom_Curve::DownCast(static_cast(c)-> + getGeometryPtr()->handle()); + Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(static_cast(p)-> + getGeometryPtr()->handle()); + + Handle_Geom2d_Curve curv1 = GeomAPI::To2d(self, plane->Pln()); + Handle_Geom2d_Curve curv2 = GeomAPI::To2d(curv, plane->Pln()); + Geom2dAPI_InterCurveCurve intCC(curv1, curv2); + int nbPoints = intCC.NbPoints(); + Py::List list; + for (int i=1; i<= nbPoints; i++) { + gp_Pnt2d pt = intCC.Point(i); + Py::Tuple tuple(2); + tuple.setItem(0, Py::Float(pt.X())); + tuple.setItem(1, Py::Float(pt.Y())); + list.append(tuple); + } + return Py::new_reference_to(list); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + Py::Float GeometryCurvePy::getFirstParameter(void) const { return Py::Float(Handle_Geom_Curve::DownCast From 9d58157aefe12af9f8d577da911106af2a24b134 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 18 Jan 2012 12:20:47 +0000 Subject: [PATCH 3/6] 0000550: No correct name of parts after import of STEP file containing assemblies embed tree widget in dialog git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5415 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Import/Gui/AppImportGuiPy.cpp | 46 ++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 0c0a30360a..8edbcada55 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -176,9 +177,9 @@ void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) { if (isRef) - createShape( label, loc, defaultname ); + createShape(label, loc, part_name); else - createShape( label, part_loc, part_name ); + createShape(label, part_loc, part_name); } else { for (TDF_ChildIterator it(label); it.More(); it.Next()) { @@ -691,10 +692,15 @@ static PyObject * exporter(PyObject *self, PyObject *args) #include #include #include +#include +#include +#include #include #include #include #include +#include +#include class OCAFBrowser { @@ -703,8 +709,6 @@ public: : pDoc(h) { myGroupIcon = QApplication::style()->standardIcon(QStyle::SP_DirIcon); - myTree = new QTreeWidget(); - myTree->setHeaderLabel(QString::fromAscii("OCAF Browser")); TDataStd::IDList(myList); myList.Append(TDataStd_TreeNode::GetDefaultTreeID()); @@ -720,7 +724,7 @@ public: myList.Append(XCAFDoc_Location::GetID()); } - void load(); + void load(QTreeWidget*); private: void load(const TDF_Label& label, QTreeWidgetItem* item, const QString&); @@ -735,22 +739,20 @@ private: private: QIcon myGroupIcon; - QTreeWidget* myTree; TDF_IDList myList; Handle_TDocStd_Document pDoc; }; -void OCAFBrowser::load() +void OCAFBrowser::load(QTreeWidget* theTree) { - myTree->clear(); + theTree->clear(); QTreeWidgetItem* root = new QTreeWidgetItem(); root->setText(0, QLatin1String("0")); root->setIcon(0, myGroupIcon); - myTree->addTopLevelItem(root); + theTree->addTopLevelItem(root); load(pDoc->GetData()->Root(), root, QString::fromAscii("0")); - myTree->show(); } void OCAFBrowser::load(const TDF_Label& label, QTreeWidgetItem* item, const QString& s) @@ -907,8 +909,30 @@ static PyObject * ocaf(PyObject *self, PyObject *args) return 0; } + static QPointer dlg = 0; + if (!dlg) { + dlg = new QDialog(Gui::getMainWindow()); + QTreeWidget* tree = new QTreeWidget(); + tree->setHeaderLabel(QString::fromAscii("OCAF Browser")); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(tree); + dlg->setLayout(layout); + + QDialogButtonBox* btn = new QDialogButtonBox(dlg); + btn->setStandardButtons(QDialogButtonBox::Close); + QObject::connect(btn, SIGNAL(rejected()), dlg, SLOT(reject())); + QHBoxLayout *boxlayout = new QHBoxLayout; + boxlayout->addWidget(btn); + layout->addLayout(boxlayout); + } + + dlg->setWindowTitle(QString::fromUtf8(file.fileName().c_str())); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); + OCAFBrowser browse(hDoc); - browse.load(); + browse.load(dlg->findChild()); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); From d4b427ed399e8979985dc9ed6d4c312c3bfe5318 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 18 Jan 2012 14:59:34 +0000 Subject: [PATCH 4/6] + use vertex instead of edge in loft function git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5416 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/PartFeatures.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp index 6e2933fdef..abbd160830 100644 --- a/src/Mod/Part/App/PartFeatures.cpp +++ b/src/Mod/Part/App/PartFeatures.cpp @@ -147,7 +147,7 @@ App::DocumentObjectExecReturn *Loft::execute(void) return new App::DocumentObjectExecReturn("Linked shape is invalid."); if (shape.ShapeType() == TopAbs_WIRE) profiles.Append(shape); - else if (shape.ShapeType() == TopAbs_EDGE) + else if (shape.ShapeType() == TopAbs_VERTEX) profiles.Append(shape); else return new App::DocumentObjectExecReturn("Linked shape is neither a vertex nor a wire."); From c4bfee57ddd90162322ead818feaacfffefdd815 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 19 Jan 2012 15:42:34 +0000 Subject: [PATCH 5/6] + simplify testing .qm files + some triangulation stuff git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5417 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/CommandTest.cpp | 21 ++++++ src/Mod/Mesh/App/Core/Algorithm.cpp | 61 ++++++++++------- src/Mod/Mesh/App/Core/TopoAlgorithm.cpp | 90 +++++++++++-------------- src/Mod/Mesh/App/Core/Triangulation.cpp | 46 ++++++++++++- src/Mod/Mesh/App/Core/Triangulation.h | 32 +++++++-- src/Mod/Test/InitGui.py | 2 +- 6 files changed, 167 insertions(+), 85 deletions(-) diff --git a/src/Gui/CommandTest.cpp b/src/Gui/CommandTest.cpp index c43fc494a4..a02a7d8e8d 100644 --- a/src/Gui/CommandTest.cpp +++ b/src/Gui/CommandTest.cpp @@ -86,6 +86,26 @@ void Std_TestQM::activated(int iMsg) } } +//=========================================================================== +// Std_TestReloadQM +//=========================================================================== +DEF_STD_CMD(Std_TestReloadQM); + +Std_TestReloadQM::Std_TestReloadQM() + : Command("Std_TestReloadQM") +{ + sGroup = "Standard-Test"; + sMenuText = "Reload translation files"; + sToolTipText = "Test function to check .qm translation files"; + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; +} + +void Std_TestReloadQM::activated(int iMsg) +{ + Translator::instance()->activateLanguage(Translator::instance()->activeLanguage().c_str()); +} + //=========================================================================== // Std_Test1 //=========================================================================== @@ -626,6 +646,7 @@ void CreateTestCommands(void) CommandManager &rcCmdMgr = Application::Instance->commandManager(); rcCmdMgr.addCommand(new Std_TestQM()); + rcCmdMgr.addCommand(new Std_TestReloadQM()); rcCmdMgr.addCommand(new FCCmdTest1()); rcCmdMgr.addCommand(new FCCmdTest2()); rcCmdMgr.addCommand(new FCCmdTest3()); diff --git a/src/Mod/Mesh/App/Core/Algorithm.cpp b/src/Mod/Mesh/App/Core/Algorithm.cpp index 512b98e777..cf051fef95 100644 --- a/src/Mod/Mesh/App/Core/Algorithm.cpp +++ b/src/Mod/Mesh/App/Core/Algorithm.cpp @@ -626,23 +626,23 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, unsigned long refPoint0 = *(boundary.begin()); unsigned long refPoint1 = *(boundary.begin()+1); if (pP2FStructure) { - const std::set& ring = (*pP2FStructure)[refPoint0]; - bool found = false; - for (std::set::const_iterator it = ring.begin(); it != ring.end() && !found; ++it) { - for (int i=0; i<3; i++) { - if (pP2FStructure->getFacet(*it)->_aulPoints[i] == refPoint1) { - rFace = *pP2FStructure->getFacet(*it); - rTriangle = _rclMesh.GetFacet(rFace); - found = true; - break; - } - } - } - } else { + const std::set& ring1 = (*pP2FStructure)[refPoint0]; + const std::set& ring2 = (*pP2FStructure)[refPoint1]; + std::vector f_int; + std::set_intersection(ring1.begin(), ring1.end(), ring2.begin(), ring2.end(), + std::back_insert_iterator >(f_int)); + if (f_int.size() != 1) + return false; // error, this must be an open edge! + + rFace = _rclMesh._aclFacetArray[f_int.front()]; + rTriangle = _rclMesh.GetFacet(rFace); + } + else { bool ready = false; for (MeshFacetArray::_TConstIterator it = _rclMesh._aclFacetArray.begin(); it != _rclMesh._aclFacetArray.end(); ++it) { for (int i=0; i<3; i++) { - if ((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i+1)%3] == refPoint1)) { + if ((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i+1)%3] == refPoint1) || + (it->_aulPoints[i] == refPoint1) && (it->_aulPoints[(i+1)%3] == refPoint0)) { rFace = *it; rTriangle = _rclMesh.GetFacet(*it); ready = true; @@ -663,7 +663,9 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, } // remove the last added point if it is duplicated + std::vector bounds = boundary; if (boundary.front() == boundary.back()) { + bounds.pop_back(); polygon.pop_back(); rPoints.pop_back(); } @@ -672,6 +674,7 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, // Afterwards we can compare the normals of the created triangles with the z-direction of our local coordinate system. // If the scalar product is positive it was a hole, otherwise not. cTria.SetPolygon(polygon); + cTria.SetIndices(bounds); std::vector surf_pts = cTria.GetPolygon(); if (pP2FStructure && level > 0) { @@ -685,7 +688,7 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, if (cTria.TriangulatePolygon()) { // if we have enough points then we fit a surface through the points and project // the added points onto this surface - cTria.ProjectOntoSurface(surf_pts); + cTria.PostProcessing(surf_pts); // get the facets and add the additional points to the array rFaces.insert(rFaces.end(), cTria.GetFacets().begin(), cTria.GetFacets().end()); std::vector newVertices = cTria.AddedPoints(); @@ -693,7 +696,7 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, rPoints.push_back((*pt)); } - // Unfortunately, the CDT algorithm does not care about the orientation of the polygon so we cannot rely on the normal + // Unfortunately, some algorithms do not care about the orientation of the polygon so we cannot rely on the normal // criterion to decide whether it's a hole or not. // std::vector faces = cTria.GetFacets(); @@ -701,11 +704,13 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, // Special case handling for a hole with three edges: the resulting facet might be coincident with the // reference facet if (faces.size()==1){ - MeshFacet first; - first._aulPoints[0] = boundary[faces.front()._aulPoints[0]]; - first._aulPoints[1] = boundary[faces.front()._aulPoints[1]]; - first._aulPoints[2] = boundary[faces.front()._aulPoints[2]]; - if ( first.IsEqual(rFace) ) { + MeshFacet first = faces.front(); + if (cTria.NeedsReindexing()) { + first._aulPoints[0] = boundary[first._aulPoints[0]]; + first._aulPoints[1] = boundary[first._aulPoints[1]]; + first._aulPoints[2] = boundary[first._aulPoints[2]]; + } + if (first.IsEqual(rFace)) { rFaces.clear(); rPoints.clear(); cTria.Discard(); @@ -717,9 +722,14 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, MeshFacet facet; unsigned short ref_side = rFace.Side(refPoint0, refPoint1); unsigned short tri_side = USHRT_MAX; + if (cTria.NeedsReindexing()) { + // the referenced indices of the polyline + refPoint0 = 0; + refPoint1 = 1; + } if (ref_side < USHRT_MAX) { for (std::vector::iterator it = faces.begin(); it != faces.end(); ++it) { - tri_side = it->Side(0, 1); + tri_side = it->Side(refPoint0, refPoint1); if (tri_side < USHRT_MAX) { facet = *it; break; @@ -737,10 +747,9 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, return false; } +#if 1 MeshGeomFacet triangle; - triangle._aclPoints[0] = rPoints[facet._aulPoints[0]]; - triangle._aclPoints[1] = rPoints[facet._aulPoints[1]]; - triangle._aclPoints[2] = rPoints[facet._aulPoints[2]]; + triangle = cTria.GetTriangle(rPoints, facet); // Now we have two adjacent triangles which we check for overlaps. // Therefore we build a separation plane that must separate the two diametrically opposed points. @@ -763,6 +772,7 @@ bool MeshAlgorithm::FillupHole(const std::vector& boundary, for (MeshFacetArray::_TIterator it = rFaces.begin(); it != rFaces.end(); ++it) it->FlipNormal(); } +#endif return true; } @@ -1764,6 +1774,7 @@ void MeshRefPointToFacets::SearchNeighbours(MeshFacetArray::_TConstIterator f_it rclNb.push_back(f_it); f_it->SetFlag(MeshFacet::VISIT); + MeshPointArray::_TConstIterator p_beg = _rclMesh.GetPoints().begin(); MeshFacetArray::_TConstIterator f_beg = _rclMesh.GetFacets().begin(); for (int i = 0; i < 3; i++) { diff --git a/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp b/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp index 86eefb06e0..11ff5c7640 100644 --- a/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp +++ b/src/Mod/Mesh/App/Core/TopoAlgorithm.cpp @@ -1237,55 +1237,20 @@ void MeshTopoAlgorithm::FillupHoles(unsigned long length, int level, std::list >& aFailed) { // get the mesh boundaries as an array of point indices - std::list > aBorders; + std::list > aBorders, aFillBorders; MeshAlgorithm cAlgo(_rclMesh); cAlgo.GetMeshBorders(aBorders); // split boundary loops if needed cAlgo.SplitBoundaryLoops(aBorders); - // get the facets to a point - MeshRefPointToFacets cPt2Fac(_rclMesh); - - MeshFacetArray newFacets; - MeshPointArray newPoints; - unsigned long numberOfOldPoints = _rclMesh._aclPointArray.size(); - for ( std::list >::iterator it = aBorders.begin(); it != aBorders.end(); ++it ) { - if ( it->size()-1 > length ) - continue; // boundary with too many edges - MeshFacetArray cFacets; - MeshPointArray cPoints; - if (cAlgo.FillupHole(*it, cTria, cFacets, cPoints, level, &cPt2Fac)) { - if (it->front() == it->back()) - it->pop_back(); - // the triangulation may produce additional points which we must take into account when appending to the mesh - unsigned long countBoundaryPoints = it->size(); - unsigned long countDifference = cPoints.size() - countBoundaryPoints; - if (countDifference > 0) { - MeshPointArray::_TIterator pt = cPoints.begin() + countBoundaryPoints; - for (unsigned long i=0; ipush_back(numberOfOldPoints++); - newPoints.push_back(*pt); - } - } - for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) { - kt->_aulPoints[0] = (*it)[kt->_aulPoints[0]]; - kt->_aulPoints[1] = (*it)[kt->_aulPoints[1]]; - kt->_aulPoints[2] = (*it)[kt->_aulPoints[2]]; - newFacets.push_back(*kt); - } - } - else { - aFailed.push_back(*it); - } + for (std::list >::iterator it = aBorders.begin(); it != aBorders.end(); ++it) { + if (it->size()-1 <= length) // ignore boundary with too many edges + aFillBorders.push_back(*it); } - // insert new points and faces into the mesh structure - _rclMesh._aclPointArray.insert(_rclMesh._aclPointArray.end(), newPoints.begin(), newPoints.end()); - for (MeshPointArray::_TIterator it = newPoints.begin(); it != newPoints.end(); ++it) - _rclMesh._clBoundBox &= *it; - if (!newFacets.empty()) - _rclMesh.AddFacets(newFacets); + if (!aFillBorders.empty()) + FillupHoles(level, cTria, aFillBorders, aFailed); } void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTria, @@ -1307,20 +1272,27 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri if (bound.front() == bound.back()) bound.pop_back(); // the triangulation may produce additional points which we must take into account when appending to the mesh - unsigned long countBoundaryPoints = bound.size(); - unsigned long countDifference = cPoints.size() - countBoundaryPoints; - if (countDifference > 0) { + if (cPoints.size() > bound.size()) { + unsigned long countBoundaryPoints = bound.size(); + unsigned long countDifference = cPoints.size() - countBoundaryPoints; MeshPointArray::_TIterator pt = cPoints.begin() + countBoundaryPoints; for (unsigned long i=0; i_aulPoints[0] = bound[kt->_aulPoints[0]]; - kt->_aulPoints[1] = bound[kt->_aulPoints[1]]; - kt->_aulPoints[2] = bound[kt->_aulPoints[2]]; - newFacets.push_back(*kt); + if (cTria.NeedsReindexing()) { + for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) { + kt->_aulPoints[0] = bound[kt->_aulPoints[0]]; + kt->_aulPoints[1] = bound[kt->_aulPoints[1]]; + kt->_aulPoints[2] = bound[kt->_aulPoints[2]]; + newFacets.push_back(*kt); + } + } + else { + for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) { + newFacets.push_back(*kt); + } } } else { @@ -1332,8 +1304,24 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri _rclMesh._aclPointArray.insert(_rclMesh._aclPointArray.end(), newPoints.begin(), newPoints.end()); for (MeshPointArray::_TIterator it = newPoints.begin(); it != newPoints.end(); ++it) _rclMesh._clBoundBox &= *it; - if (!newFacets.empty()) - _rclMesh.AddFacets(newFacets); + if (!newFacets.empty()) { + // Do some checks for invalid point indices + MeshFacetArray addFacets; + addFacets.reserve(newFacets.size()); + unsigned long ctPoints = _rclMesh.CountPoints(); + for (MeshFacetArray::_TIterator it = newFacets.begin(); it != newFacets.end(); ++it) { + if (it->_aulPoints[0] >= ctPoints || + it->_aulPoints[1] >= ctPoints || + it->_aulPoints[2] >= ctPoints) { + Base::Console().Log("Ignore invalid face <%d, %d, %d> (%d vertices)\n", + it->_aulPoints[0], it->_aulPoints[1], it->_aulPoints[2], ctPoints); + } + else { + addFacets.push_back(*it); + } + } + _rclMesh.AddFacets(addFacets); + } } void MeshTopoAlgorithm::FindHoles(unsigned long length, diff --git a/src/Mod/Mesh/App/Core/Triangulation.cpp b/src/Mod/Mesh/App/Core/Triangulation.cpp index 6fecbd780d..68babf99df 100644 --- a/src/Mod/Mesh/App/Core/Triangulation.cpp +++ b/src/Mod/Mesh/App/Core/Triangulation.cpp @@ -30,6 +30,7 @@ #include #include "Triangulation.h" #include "Approximation.h" +#include "Algorithm.h" #include "MeshKernel.h" #include @@ -121,7 +122,7 @@ std::vector AbstractPolygonTriangulator::ProjectToFitPlane() return proj; } -void AbstractPolygonTriangulator::ProjectOntoSurface(const std::vector& points) +void AbstractPolygonTriangulator::PostProcessing(const std::vector& points) { // For a good approximation we should have enough points, i.e. for 9 parameters // for the fit function we should have at least 50 points. @@ -144,9 +145,23 @@ void AbstractPolygonTriangulator::ProjectOntoSurface(const std::vector_points.size() != this->_indices.size()) { + Base::Console().Log("Triangulation: %d points <> %d indices\n", _points.size(), _indices.size()); + return false; + } bool ok = Triangulate(); if (ok) Done(); return ok; @@ -177,6 +192,10 @@ void AbstractPolygonTriangulator::Discard() } } +void AbstractPolygonTriangulator::Reset() +{ +} + void AbstractPolygonTriangulator::Done() { _info.push_back(_points.size()); @@ -625,7 +644,7 @@ bool FlatTriangulator::Triangulate() return succeeded; } -void FlatTriangulator::ProjectOntoSurface(const std::vector&) +void FlatTriangulator::PostProcessing(const std::vector&) { } @@ -669,7 +688,8 @@ bool ConstraintDelaunayTriangulator::Triangulate() // ------------------------------------------------------------- -Triangulator::Triangulator(const MeshKernel& k) : _kernel(k) +#if 0 +Triangulator::Triangulator(const MeshKernel& k, bool flat) : _kernel(k) { } @@ -681,3 +701,23 @@ bool Triangulator::Triangulate() { return false; } + +MeshGeomFacet Triangulator::GetTriangle(const MeshPointArray&, + const MeshFacet& facet) const +{ + return MeshGeomFacet(); +} + +void Triangulator::PostProcessing(const std::vector&) +{ +} + +void Triangulator::Discard() +{ + AbstractPolygonTriangulator::Discard(); +} + +void Triangulator::Reset() +{ +} +#endif diff --git a/src/Mod/Mesh/App/Core/Triangulation.h b/src/Mod/Mesh/App/Core/Triangulation.h index a33b5a0d98..0d75e2a3b3 100644 --- a/src/Mod/Mesh/App/Core/Triangulation.h +++ b/src/Mod/Mesh/App/Core/Triangulation.h @@ -39,6 +39,15 @@ public: /** Sets the polygon to be triangulated. */ void SetPolygon(const std::vector& raclPoints); + void SetIndices(const std::vector& d) {_indices = d;} + /** Usually the created faces use the indices of the polygon points + * from [0, n]. If the faces should be appended to an existing mesh + * they may need to be reindexed from the calling instance. + * However, there may other algorithms that directly use the indices + * of the mesh and thus do not need to be touched afterwards. In this + * case the method should be reimplemented to return false. + */ + virtual bool NeedsReindexing() const { return true; } /** Get the polygon points to be triangulated. The points may be * projected onto its average plane. */ @@ -46,7 +55,7 @@ public: /** The triangulation algorithm may create new points when * calling Triangulate(). This method returns these added * points. - * @note: Make sure to have called ProjectOntoSurface() before using + * @note: Make sure to have called PostProcessing() before using * this method if you want the surface points the new points are lying on. */ std::vector AddedPoints() const; @@ -65,11 +74,13 @@ public: /** If points were added then we get the 3D points by projecting the added * 2D points onto a surface which fits into the given points. */ - virtual void ProjectOntoSurface(const std::vector&); + virtual void PostProcessing(const std::vector&); /** Returns the geometric triangles of the polygon. */ const std::vector& GetTriangles() const { return _triangles;} /** Returns the topologic facets of the polygon. */ const std::vector& GetFacets() const { return _facets;} + /** Returns the the triangle to a given topologic facet. */ + virtual MeshGeomFacet GetTriangle(const MeshPointArray&, const MeshFacet&) const; /** Returns the length of the polygon */ float GetLength() const; /** Get information about the pol GetInfo() const; - void Discard(); + virtual void Discard(); + /** Resets some internals. The default implementation does nothing.*/ + virtual void Reset(); protected: /** Computes the triangulation of a polygon. The resulting facets can @@ -89,6 +102,7 @@ protected: protected: bool _discard; Base::Matrix4D _inverse; + std::vector _indices; std::vector _points; std::vector _newpoints; std::vector _triangles; @@ -168,7 +182,7 @@ public: FlatTriangulator(); ~FlatTriangulator(); - void ProjectOntoSurface(const std::vector&); + void PostProcessing(const std::vector&); protected: bool Triangulate(); @@ -187,17 +201,25 @@ private: float fMaxArea; }; +#if 0 class MeshExport Triangulator : public AbstractPolygonTriangulator { public: - Triangulator(const MeshKernel&); + Triangulator(const MeshKernel&, bool flat); ~Triangulator(); + void Discard(); + void Reset(); + + bool NeedsReindexing() const { return false; } + MeshGeomFacet GetTriangle(const MeshPointArray&, const MeshFacet&) const; + void PostProcessing(const std::vector&); protected: bool Triangulate(); const MeshKernel& _kernel; }; +#endif } // namespace MeshCore diff --git a/src/Mod/Test/InitGui.py b/src/Mod/Test/InitGui.py index 9a75758658..22cebd4d02 100644 --- a/src/Mod/Test/InitGui.py +++ b/src/Mod/Test/InitGui.py @@ -63,7 +63,7 @@ class TestWorkbench ( Workbench ): self.appendToolbar("TestTools",list) menu = ["Test &Commands","TestToolsGui"] - list = ["Std_TestQM","Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"] + list = ["Std_TestQM","Std_TestReloadQM","Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"] self.appendCommandbar("TestToolsGui",list) self.appendMenu(menu,list) From ecd91a0f97b4195f51755708d5b741144809a70a Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 20 Jan 2012 00:10:01 +0000 Subject: [PATCH 6/6] + patch for ldf module (Milos Koutny) git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5418 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Idf/Idf.py | 32 +++++++++--------- src/Mod/Idf/Init.py | 4 +-- src/Mod/Idf/lib/footprints_models.csv | 48 +++++++++++++-------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/Mod/Idf/Idf.py b/src/Mod/Idf/Idf.py index efbac6027d..668aa6eaee 100644 --- a/src/Mod/Idf/Idf.py +++ b/src/Mod/Idf/Idf.py @@ -1,5 +1,5 @@ #*************************************************************************** -#* (c) Milos Koutny (milos.koutny@gmail.com) 2010 * +#* (c) Milos Koutny (milos.koutny@gmail.com) 2012 * #* * #* This file is part of the FreeCAD CAx development system. * #* * @@ -22,36 +22,38 @@ #* Milos Koutny 2010 * #***************************************************************************/ -import FreeCAD, Part, os, FreeCADGui, draftGui +import FreeCAD, Part, os, FreeCADGui, __builtin__ from FreeCAD import Base from math import * ########################################################## -# Script version dated 17-May-2010 # +# Script version dated 19-Jan-2012 # ########################################################## #Configuration parameters below - use standard slashes / # ########################################################## -#model_tab_filename="c:/libraries/3d_libraries/brno_cis/brno_footprints_models.csv" +## path to table file (simple comma separated values) + model_tab_filename = FreeCAD.getResourceDir()+ "Mod/Idf/lib/footprints_models.csv" -#step_path="c:/libraries/3d_libraries/brno_cis/step/" + +## path to directory containing step models + step_path=FreeCAD.getResourceDir()+ "Mod/Idf/lib/" -#model_tab_filename="c:/Libraries/3d_libraries/tandberg/footprints_models.csv" -#step_path="c:/Libraries/3d_libraries/tandberg/step/" + ignore_hole_size=1 # size in MM to prevent huge number of drilled holes EmpDisplayMode=2 # 0='Flat Lines', 1='Shaded', 2='Wireframe', 3='Points'; recommended 2 or 0 IDF_sort=0 # 0-sort per refdes [1 - part number (not preffered)/refdes] 2-sort per footprint/refdes IDF_diag=1 # 0/1=disabled/enabled output (footprint.lst/missing_models.lst) -IDF_diag_path="C:/temp" # path for output of footprint.lst and missing_models.lst +IDF_diag_path="/tmp" # path for output of footprint.lst and missing_models.lst ######################################################################################## # End config section do not touch code below # ######################################################################################## -pythonopen = open # to distinguish python built-in open function from the one declared here +pythonopen = __builtin__.open # to distinguish python built-in open function from the one declared here def open(filename): """called when freecad opens an Emn file""" @@ -176,11 +178,11 @@ def Process_board_outline(doc,board_outline,drills,board_thickness): outline=outline.cut(Part.Face(out_shape)) doc_outline=doc.addObject("Part::Feature","Board_outline") doc_outline.Shape=outline - FreeCADGui.Selection.addSelection(doc_outline) - FreeCADGui.runCommand("Draft_Upgrade") - outline=FreeCAD.ActiveDocument.getObject("Union").Shape - FreeCAD.ActiveDocument.removeObject("Union") - doc_outline=doc.addObject("Part::Feature","Board_outline") + #FreeCADGui.Selection.addSelection(doc_outline) + #FreeCADGui.runCommand("Draft_Upgrade") + #outline=FreeCAD.ActiveDocument.getObject("Union").Shape + #FreeCAD.ActiveDocument.removeObject("Union") + #doc_outline=doc.addObject("Part::Feature","Board_outline") doc_outline.Shape=outline.extrude(Base.Vector(0,0,-board_thickness)) grp=doc.addObject("App::DocumentObjectGroup", "Board_Geoms") grp.addObject(doc_outline) @@ -342,7 +344,7 @@ def place_steps(doc,placement,board_thickness): FreeCAD.Console.PrintMessage("Step models to be loaded for footprints: "+str(validkeys)+"\n") grp=doc.addObject("App::DocumentObjectGroup", "Step Models") for validkey in validkeys: - step_dict.append((validkey,Part.read(step_path+"/"+model_dict[validkey]))) + step_dict.append((validkey,Part.read(step_path+model_dict[validkey]))) FreeCAD.Console.PrintMessage("Reading step file "+str(model_dict[validkey])+" for footprint "+str(validkey)+"\n") step_dict=dict(step_dict) for place_item in placement: diff --git a/src/Mod/Idf/Init.py b/src/Mod/Idf/Init.py index 00cb755664..0dcfb40537 100644 --- a/src/Mod/Idf/Init.py +++ b/src/Mod/Idf/Init.py @@ -31,6 +31,6 @@ -# two options for IDF added by Milos Koutny (12-Feb-2010) +# an option for IDF added by Milos Koutny (12-Feb-2010) FreeCAD.addImportType("IDF emn file File Type (*.emn)","Idf") -#FreeCAD.addImportType("IDF emp File Type (*.emp)","Import_Emp") + diff --git a/src/Mod/Idf/lib/footprints_models.csv b/src/Mod/Idf/lib/footprints_models.csv index 6a69ef8486..ac49ec3720 100644 --- a/src/Mod/Idf/lib/footprints_models.csv +++ b/src/Mod/Idf/lib/footprints_models.csv @@ -1,28 +1,28 @@ "FOOTPRINT" "STEP FILE" -"SOT23-R" "SOT23.STP" -"SMD_C_0805-R" "0805_SMD.STP" -"SMD_C_1210-R" "1210_SMD.STP" -"SMD_R_1206-R" "1206_SMD.STP" -"SMD_C_0603-R" "0603_SMD.STP" -"SMD_R_0603-R" "0603_SMD.STP" -"MINISMDC-1812-R" "1812_SMD.STP" -"SMD_C_2225-R" "2225_SMD.STP" -"SMD_R_2512-R" "2512_SMD.STP" -"1812PS" "1812_SMD.STP" -"TSSOP8_065M-R" "TSS0P_8.STP" -"MSOP10E_LT" "MSOP_10.STP" -"TCMT11XX" "TCMT1107_4.STP" -"SMB-TB" "SMB_DO_214AA.STP" -"SOT404-GDS-R" "SOT404.STP" -"SOT428-A1-A2C-R" "SOT428_DPAK.STP" -"SOT96-1-R" "SOT_96.STP" -"SOT323-BEC-R" "SOT_323_3.STP" -"SOD523-R" "SOD_523.STP" -"SMC" "SMC_DO_214AB.STP" -"SOD523-R" "SOD_523.STP" -"TSM-104-01-L-DV" "TSM_104_01_L_DV_A.STP" -"TSM-103-01-L-DV-A" "TSM_103_01_L_DV_A.STP" -"SOD323-R" "SOD_323.STP" +"SOT23-R" "SOT23.stp" +"SMD_C_0805-R" "0805_SMD.stp" +"SMD_C_1210-R" "1210_SMD.stp" +"SMD_R_1206-R" "1206_SMD.stp" +"SMD_C_0603-R" "0603_SMD.stp" +"SMD_R_0603-R" "0603_SMD.stp" +"MINISMDC-1812-R" "1812_SMD.stp" +"SMD_C_2225-R" "2225_SMD.stp" +"SMD_R_2512-R" "2512_SMD.stp" +"1812PS" "1812_SMD.stp" +"TSSOP8_065M-R" "TSS0P_8.stp" +"MSOP10E_LT" "MSOP_10.stp" +"TCMT11XX" "TCMT1107_4.stp" +"SMB-TB" "SMB_DO_214AA.stp" +"SOT404-GDS-R" "SOT404.stp" +"SOT428-A1-A2C-R" "SOT428_DPAK.stp" +"SOT96-1-R" "SOT_96.stp" +"SOT323-BEC-R" "SOT_323_3.stp" +"SOD523-R" "SOD_523.stp" +"SMC" "SMC_DO_214AB.stp" +"SOD523-R" "SOD_523.stp" +"TSM-104-01-L-DV" "TSM_104_01_L_DV_A.stp" +"TSM-103-01-L-DV-A" "TSM_103_01_L_DV_A.stp" +"SOD323-R" "SOD_323.stp" "VC0603-R" "VC0603_SMD.stp" "RLF12545" "RLF_12545.stp" "CAPAE830X1050" "CAP_50SGV_8_10.stp"