diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index df7c93b30a20..e5525ebc94d9 100644 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -1,148 +1,148 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 -#endif - -#include -#include -#include - -#include "FemMeshPy.h" -#include "FemMesh.h" -#include "FemMeshProperty.h" -#include "FemAnalysis.h" -#include "FemMeshObject.h" -#include "FemMeshShapeObject.h" -#include "FemMeshShapeNetgenObject.h" - -#include "FemSetElementsObject.h" -#include "FemSetFacesObject.h" -#include "FemSetGeometryObject.h" -#include "FemSetNodesObject.h" - -#include "HypothesisPy.h" -#include "FemConstraintBearing.h" -#include "FemConstraintFixed.h" -#include "FemConstraintForce.h" -#include "FemConstraintPressure.h" -#include "FemConstraintGear.h" -#include "FemConstraintPulley.h" -#include "FemConstraintDisplacement.h" - -#include "FemResultObject.h" -#include "FemSolverObject.h" - -namespace Fem { -extern PyObject* initModule(); -} - -/* Python entry */ -PyMODINIT_FUNC initFem() -{ - // load dependend module - try { - Base::Interpreter().loadModule("Part"); - //Base::Interpreter().loadModule("Mesh"); - } - catch(const Base::Exception& e) { - PyErr_SetString(PyExc_ImportError, e.what()); - return; - } - PyObject* femModule = Fem::initModule(); - Base::Console().Log("Loading Fem module... done\n"); - - Fem::StdMeshers_Arithmetic1DPy ::init_type(femModule); - Fem::StdMeshers_AutomaticLengthPy ::init_type(femModule); - Fem::StdMeshers_NotConformAllowedPy ::init_type(femModule); - Fem::StdMeshers_MaxLengthPy ::init_type(femModule); - Fem::StdMeshers_LocalLengthPy ::init_type(femModule); - Fem::StdMeshers_QuadranglePreferencePy ::init_type(femModule); - Fem::StdMeshers_Quadrangle_2DPy ::init_type(femModule); - Fem::StdMeshers_MaxElementAreaPy ::init_type(femModule); - Fem::StdMeshers_Regular_1DPy ::init_type(femModule); - Fem::StdMeshers_UseExisting_1DPy ::init_type(femModule); - Fem::StdMeshers_UseExisting_2DPy ::init_type(femModule); - Fem::StdMeshers_CompositeSegment_1DPy ::init_type(femModule); - Fem::StdMeshers_Deflection1DPy ::init_type(femModule); - Fem::StdMeshers_LayerDistributionPy ::init_type(femModule); - Fem::StdMeshers_LengthFromEdgesPy ::init_type(femModule); - Fem::StdMeshers_MaxElementVolumePy ::init_type(femModule); - Fem::StdMeshers_MEFISTO_2DPy ::init_type(femModule); - Fem::StdMeshers_NumberOfLayersPy ::init_type(femModule); - Fem::StdMeshers_NumberOfSegmentsPy ::init_type(femModule); - Fem::StdMeshers_Prism_3DPy ::init_type(femModule); - Fem::StdMeshers_Projection_1DPy ::init_type(femModule); - Fem::StdMeshers_Projection_2DPy ::init_type(femModule); - Fem::StdMeshers_Projection_3DPy ::init_type(femModule); - Fem::StdMeshers_ProjectionSource1DPy ::init_type(femModule); - Fem::StdMeshers_ProjectionSource2DPy ::init_type(femModule); - Fem::StdMeshers_ProjectionSource3DPy ::init_type(femModule); - Fem::StdMeshers_QuadraticMeshPy ::init_type(femModule); - Fem::StdMeshers_RadialPrism_3DPy ::init_type(femModule); - Fem::StdMeshers_SegmentAroundVertex_0DPy ::init_type(femModule); - Fem::StdMeshers_SegmentLengthAroundVertexPy ::init_type(femModule); - Fem::StdMeshers_StartEndLengthPy ::init_type(femModule); - Fem::StdMeshers_TrianglePreferencePy ::init_type(femModule); - Fem::StdMeshers_Hexa_3DPy ::init_type(femModule); - - // Add Types to module - Base::Interpreter().addType(&Fem::FemMeshPy::Type,femModule,"FemMesh"); - - - // NOTE: To finish the initialization of our own type objects we must - // call PyType_Ready, otherwise we run into a segmentation fault, later on. - // This function is responsible for adding inherited slots from a type's base class. - - Fem::FemAnalysis ::init(); - Fem::FemAnalysisPython ::init(); - Fem::DocumentObject ::init(); - Fem::FeaturePython ::init(); - Fem::FemMesh ::init(); - Fem::FemMeshObject ::init(); - Fem::FemMeshShapeObject ::init(); - Fem::FemMeshShapeNetgenObject ::init(); - Fem::PropertyFemMesh ::init(); - - Fem::FemSetObject ::init(); - Fem::FemSetElementsObject ::init(); - Fem::FemSetFacesObject ::init(); - Fem::FemSetGeometryObject ::init(); - Fem::FemSetNodesObject ::init(); - - Fem::Constraint ::init(); - Fem::ConstraintBearing ::init(); - Fem::ConstraintFixed ::init(); - Fem::ConstraintForce ::init(); - Fem::ConstraintPressure ::init(); - Fem::ConstraintGear ::init(); - Fem::ConstraintPulley ::init(); - Fem::ConstraintDisplacement ::init(); - - Fem::FemResultObject ::init(); - Fem::FemResultObjectPython ::init(); - Fem::FemSolverObject ::init(); - Fem::FemSolverObjectPython ::init(); -} +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 +#endif + +#include +#include +#include + +#include "FemMeshPy.h" +#include "FemMesh.h" +#include "FemMeshProperty.h" +#include "FemAnalysis.h" +#include "FemMeshObject.h" +#include "FemMeshShapeObject.h" +#include "FemMeshShapeNetgenObject.h" + +#include "FemSetElementsObject.h" +#include "FemSetFacesObject.h" +#include "FemSetGeometryObject.h" +#include "FemSetNodesObject.h" + +#include "HypothesisPy.h" +#include "FemConstraintBearing.h" +#include "FemConstraintFixed.h" +#include "FemConstraintForce.h" +#include "FemConstraintPressure.h" +#include "FemConstraintGear.h" +#include "FemConstraintPulley.h" +#include "FemConstraintDisplacement.h" + +#include "FemResultObject.h" +#include "FemSolverObject.h" + +namespace Fem { +extern PyObject* initModule(); +} + +/* Python entry */ +PyMODINIT_FUNC initFem() +{ + // load dependend module + try { + Base::Interpreter().loadModule("Part"); + //Base::Interpreter().loadModule("Mesh"); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ImportError, e.what()); + return; + } + PyObject* femModule = Fem::initModule(); + Base::Console().Log("Loading Fem module... done\n"); + + Fem::StdMeshers_Arithmetic1DPy ::init_type(femModule); + Fem::StdMeshers_AutomaticLengthPy ::init_type(femModule); + Fem::StdMeshers_NotConformAllowedPy ::init_type(femModule); + Fem::StdMeshers_MaxLengthPy ::init_type(femModule); + Fem::StdMeshers_LocalLengthPy ::init_type(femModule); + Fem::StdMeshers_QuadranglePreferencePy ::init_type(femModule); + Fem::StdMeshers_Quadrangle_2DPy ::init_type(femModule); + Fem::StdMeshers_MaxElementAreaPy ::init_type(femModule); + Fem::StdMeshers_Regular_1DPy ::init_type(femModule); + Fem::StdMeshers_UseExisting_1DPy ::init_type(femModule); + Fem::StdMeshers_UseExisting_2DPy ::init_type(femModule); + Fem::StdMeshers_CompositeSegment_1DPy ::init_type(femModule); + Fem::StdMeshers_Deflection1DPy ::init_type(femModule); + Fem::StdMeshers_LayerDistributionPy ::init_type(femModule); + Fem::StdMeshers_LengthFromEdgesPy ::init_type(femModule); + Fem::StdMeshers_MaxElementVolumePy ::init_type(femModule); + Fem::StdMeshers_MEFISTO_2DPy ::init_type(femModule); + Fem::StdMeshers_NumberOfLayersPy ::init_type(femModule); + Fem::StdMeshers_NumberOfSegmentsPy ::init_type(femModule); + Fem::StdMeshers_Prism_3DPy ::init_type(femModule); + Fem::StdMeshers_Projection_1DPy ::init_type(femModule); + Fem::StdMeshers_Projection_2DPy ::init_type(femModule); + Fem::StdMeshers_Projection_3DPy ::init_type(femModule); + Fem::StdMeshers_ProjectionSource1DPy ::init_type(femModule); + Fem::StdMeshers_ProjectionSource2DPy ::init_type(femModule); + Fem::StdMeshers_ProjectionSource3DPy ::init_type(femModule); + Fem::StdMeshers_QuadraticMeshPy ::init_type(femModule); + Fem::StdMeshers_RadialPrism_3DPy ::init_type(femModule); + Fem::StdMeshers_SegmentAroundVertex_0DPy ::init_type(femModule); + Fem::StdMeshers_SegmentLengthAroundVertexPy ::init_type(femModule); + Fem::StdMeshers_StartEndLengthPy ::init_type(femModule); + Fem::StdMeshers_TrianglePreferencePy ::init_type(femModule); + Fem::StdMeshers_Hexa_3DPy ::init_type(femModule); + + // Add Types to module + Base::Interpreter().addType(&Fem::FemMeshPy::Type,femModule,"FemMesh"); + + + // NOTE: To finish the initialization of our own type objects we must + // call PyType_Ready, otherwise we run into a segmentation fault, later on. + // This function is responsible for adding inherited slots from a type's base class. + + Fem::FemAnalysis ::init(); + Fem::FemAnalysisPython ::init(); + Fem::DocumentObject ::init(); + Fem::FeaturePython ::init(); + Fem::FemMesh ::init(); + Fem::FemMeshObject ::init(); + Fem::FemMeshShapeObject ::init(); + Fem::FemMeshShapeNetgenObject ::init(); + Fem::PropertyFemMesh ::init(); + + Fem::FemSetObject ::init(); + Fem::FemSetElementsObject ::init(); + Fem::FemSetFacesObject ::init(); + Fem::FemSetGeometryObject ::init(); + Fem::FemSetNodesObject ::init(); + + Fem::Constraint ::init(); + Fem::ConstraintBearing ::init(); + Fem::ConstraintFixed ::init(); + Fem::ConstraintForce ::init(); + Fem::ConstraintPressure ::init(); + Fem::ConstraintGear ::init(); + Fem::ConstraintPulley ::init(); + Fem::ConstraintDisplacement ::init(); + + Fem::FemResultObject ::init(); + Fem::FemResultObjectPython ::init(); + Fem::FemSolverObject ::init(); + Fem::FemSolverObjectPython ::init(); +} diff --git a/src/Mod/Fem/App/AppFemPy.cpp b/src/Mod/Fem/App/AppFemPy.cpp index 22c38329800f..10bc5dad6eec 100644 --- a/src/Mod/Fem/App/AppFemPy.cpp +++ b/src/Mod/Fem/App/AppFemPy.cpp @@ -1,243 +1,243 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 -# include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "FemMesh.h" -#include "FemMeshObject.h" -#include "FemMeshPy.h" - -#include - -#include -#include -#include - -namespace Fem { -class Module : public Py::ExtensionModule -{ -public: - Module() : Py::ExtensionModule("Fem") - { - add_varargs_method("open",&Module::open, - "open(string) -- Create a new document and a Mesh::Import feature to load the file into the document." - ); - add_varargs_method("insert",&Module::insert, - "insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document." - ); - add_varargs_method("export",&Module::exporter, - "export(list,string) -- Export a list of objects into a single file." - ); - add_varargs_method("read",&Module::read, - "Read a mesh from a file and returns a Mesh object." - ); - add_varargs_method("show",&Module::show, - "show(shape) -- Add the shape to the active document or create one if no document exists." - ); - initialize("This module is the Fem module."); // register with Python - } - - virtual ~Module() {} - -private: - virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) - { - try { - return Py::ExtensionModule::invoke_method_varargs(method_def, args); - } - catch (const Standard_Failure &e) { - std::string str; - Standard_CString msg = e.GetMessageString(); - str += typeid(e).name(); - str += " "; - if (msg) {str += msg;} - else {str += "No OCCT Exception Message";} - throw Py::Exception(Part::PartExceptionOCCError, str); - } - catch (const Base::Exception &e) { - throw Py::RuntimeError(e.what()); - } - catch (const std::exception &e) { - throw Py::RuntimeError(e.what()); - } - } - Py::Object open(const Py::Tuple& args) - { - char* Name; - if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) - throw Py::Exception(); - - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - std::auto_ptr mesh(new FemMesh); - mesh->read(EncodedName.c_str()); - Base::FileInfo file(EncodedName.c_str()); - // create new document and add Import feature - App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); - FemMeshObject *pcFeature = static_cast - (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str())); - pcFeature->Label.setValue(file.fileNamePure().c_str()); - pcFeature->FemMesh.setValuePtr(mesh.get()); - (void)mesh.release(); - pcFeature->purgeTouched(); - - return Py::None(); - } - Py::Object insert(const Py::Tuple& args) - { - char* Name; - const char* DocName = 0; - if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) - throw Py::Exception(); - - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - App::Document *pcDoc = 0; - if (DocName) - pcDoc = App::GetApplication().getDocument(DocName); - else - pcDoc = App::GetApplication().getActiveDocument(); - - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument(DocName); - } - - std::auto_ptr mesh(new FemMesh); - mesh->read(EncodedName.c_str()); - Base::FileInfo file(EncodedName.c_str()); - - FemMeshObject *pcFeature = static_cast - (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str())); - pcFeature->Label.setValue(file.fileNamePure().c_str()); - pcFeature->FemMesh.setValuePtr(mesh.get()); - (void)mesh.release(); - pcFeature->purgeTouched(); - - return Py::None(); - } - Py::Object exporter(const Py::Tuple& args) - { - PyObject* object; - char* Name; - if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) - throw Py::Exception(); - - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - Py::Sequence list(object); - Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject"); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - PyObject* item = (*it).ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(meshId)) { - static_cast(obj)->FemMesh.getValue().write(EncodedName.c_str()); - break; - } - } - } - - return Py::None(); - } - Py::Object read(const Py::Tuple& args) - { - char* Name; - if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) - throw Py::Exception(); - - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - std::auto_ptr mesh(new FemMesh); - mesh->read(EncodedName.c_str()); - return Py::asObject(new FemMeshPy(mesh.release())); - } - Py::Object show(const Py::Tuple& args) - { - PyObject *pcObj; - if (!PyArg_ParseTuple(args.ptr(), "O!", &(FemMeshPy::Type), &pcObj)) - throw Py::Exception(); - - App::Document *pcDoc = App::GetApplication().getActiveDocument(); - if (!pcDoc) - pcDoc = App::GetApplication().newDocument(); - - FemMeshPy* pShape = static_cast(pcObj); - Fem::FemMeshObject *pcFeature = (Fem::FemMeshObject *)pcDoc->addObject("Fem::FemMeshObject", "Mesh"); - // copy the data - //TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr()); - pcFeature->FemMesh.setValue(*(pShape->getFemMeshPtr())); - pcDoc->recompute(); - - return Py::None(); - } -}; - -PyObject* initModule() -{ - return (new Module)->module().ptr(); -} - -} // namespace Fem +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 +# include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "FemMesh.h" +#include "FemMeshObject.h" +#include "FemMeshPy.h" + +#include + +#include +#include +#include + +namespace Fem { +class Module : public Py::ExtensionModule +{ +public: + Module() : Py::ExtensionModule("Fem") + { + add_varargs_method("open",&Module::open, + "open(string) -- Create a new document and a Mesh::Import feature to load the file into the document." + ); + add_varargs_method("insert",&Module::insert, + "insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document." + ); + add_varargs_method("export",&Module::exporter, + "export(list,string) -- Export a list of objects into a single file." + ); + add_varargs_method("read",&Module::read, + "Read a mesh from a file and returns a Mesh object." + ); + add_varargs_method("show",&Module::show, + "show(shape) -- Add the shape to the active document or create one if no document exists." + ); + initialize("This module is the Fem module."); // register with Python + } + + virtual ~Module() {} + +private: + virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) + { + try { + return Py::ExtensionModule::invoke_method_varargs(method_def, args); + } + catch (const Standard_Failure &e) { + std::string str; + Standard_CString msg = e.GetMessageString(); + str += typeid(e).name(); + str += " "; + if (msg) {str += msg;} + else {str += "No OCCT Exception Message";} + throw Py::Exception(Part::PartExceptionOCCError, str); + } + catch (const Base::Exception &e) { + throw Py::RuntimeError(e.what()); + } + catch (const std::exception &e) { + throw Py::RuntimeError(e.what()); + } + } + Py::Object open(const Py::Tuple& args) + { + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + std::auto_ptr mesh(new FemMesh); + mesh->read(EncodedName.c_str()); + Base::FileInfo file(EncodedName.c_str()); + // create new document and add Import feature + App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); + FemMeshObject *pcFeature = static_cast + (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str())); + pcFeature->Label.setValue(file.fileNamePure().c_str()); + pcFeature->FemMesh.setValuePtr(mesh.get()); + (void)mesh.release(); + pcFeature->purgeTouched(); + + return Py::None(); + } + Py::Object insert(const Py::Tuple& args) + { + char* Name; + const char* DocName = 0; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + App::Document *pcDoc = 0; + if (DocName) + pcDoc = App::GetApplication().getDocument(DocName); + else + pcDoc = App::GetApplication().getActiveDocument(); + + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument(DocName); + } + + std::auto_ptr mesh(new FemMesh); + mesh->read(EncodedName.c_str()); + Base::FileInfo file(EncodedName.c_str()); + + FemMeshObject *pcFeature = static_cast + (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str())); + pcFeature->Label.setValue(file.fileNamePure().c_str()); + pcFeature->FemMesh.setValuePtr(mesh.get()); + (void)mesh.release(); + pcFeature->purgeTouched(); + + return Py::None(); + } + Py::Object exporter(const Py::Tuple& args) + { + PyObject* object; + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + Py::Sequence list(object); + Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject"); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* item = (*it).ptr(); + if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); + if (obj->getTypeId().isDerivedFrom(meshId)) { + static_cast(obj)->FemMesh.getValue().write(EncodedName.c_str()); + break; + } + } + } + + return Py::None(); + } + Py::Object read(const Py::Tuple& args) + { + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + std::auto_ptr mesh(new FemMesh); + mesh->read(EncodedName.c_str()); + return Py::asObject(new FemMeshPy(mesh.release())); + } + Py::Object show(const Py::Tuple& args) + { + PyObject *pcObj; + if (!PyArg_ParseTuple(args.ptr(), "O!", &(FemMeshPy::Type), &pcObj)) + throw Py::Exception(); + + App::Document *pcDoc = App::GetApplication().getActiveDocument(); + if (!pcDoc) + pcDoc = App::GetApplication().newDocument(); + + FemMeshPy* pShape = static_cast(pcObj); + Fem::FemMeshObject *pcFeature = (Fem::FemMeshObject *)pcDoc->addObject("Fem::FemMeshObject", "Mesh"); + // copy the data + //TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr()); + pcFeature->FemMesh.setValue(*(pShape->getFemMeshPtr())); + pcDoc->recompute(); + + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); +} + +} // namespace Fem diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index facc0c665fb1..51332acf2de1 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -1,81 +1,81 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINT_H -#define FEM_CONSTRAINT_H - -#include -#include -#include -#include - -namespace Fem -{ - -class AppFemExport Constraint : public App::DocumentObject -{ - PROPERTY_HEADER(Fem::Constraint); - -public: - /// Constructor - Constraint(void); - virtual ~Constraint(); - - App::PropertyLinkSubList References; - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyVector NormalDirection; - - //OvG: Scale - App::PropertyInteger Scale; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraint"; - } - - //OvG: Allow automatic determination of scaling of constraint drawings, e.g. arrow length and size - int calcDrawScaleFactor(double lparam) const; - int calcDrawScaleFactor(double lvparam, double luparam) const; - int calcDrawScaleFactor() const; - -protected: - virtual void onChanged(const App::Property* prop); - virtual void onDocumentRestored(); - -protected: - /// Calculate the points where symbols should be drawn - const bool getPoints(std::vector& points, std::vector& normals, int * scale) const; //OvG: added scale parameter - const bool getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const; - Base::Vector3d getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, - const App::PropertyLinkSub &location, const double& dist); - const Base::Vector3d getDirection(const App::PropertyLinkSub &direction); - -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINT_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINT_H +#define FEM_CONSTRAINT_H + +#include +#include +#include +#include + +namespace Fem +{ + +class AppFemExport Constraint : public App::DocumentObject +{ + PROPERTY_HEADER(Fem::Constraint); + +public: + /// Constructor + Constraint(void); + virtual ~Constraint(); + + App::PropertyLinkSubList References; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVector NormalDirection; + + //OvG: Scale + App::PropertyInteger Scale; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraint"; + } + + //OvG: Allow automatic determination of scaling of constraint drawings, e.g. arrow length and size + int calcDrawScaleFactor(double lparam) const; + int calcDrawScaleFactor(double lvparam, double luparam) const; + int calcDrawScaleFactor() const; + +protected: + virtual void onChanged(const App::Property* prop); + virtual void onDocumentRestored(); + +protected: + /// Calculate the points where symbols should be drawn + const bool getPoints(std::vector& points, std::vector& normals, int * scale) const; //OvG: added scale parameter + const bool getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const; + Base::Vector3d getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, + const App::PropertyLinkSub &location, const double& dist); + const Base::Vector3d getDirection(const App::PropertyLinkSub &direction); + +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINT_H diff --git a/src/Mod/Fem/App/FemConstraintBearing.cpp b/src/Mod/Fem/App/FemConstraintBearing.cpp index 5eab9e8b52b5..c3609415e13f 100644 --- a/src/Mod/Fem/App/FemConstraintBearing.cpp +++ b/src/Mod/Fem/App/FemConstraintBearing.cpp @@ -1,117 +1,117 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#include -#include -#include -#include -#include -#include -#endif - -#include "FemConstraintBearing.h" - -#include -#include - -using namespace Fem; - -PROPERTY_SOURCE(Fem::ConstraintBearing, Fem::Constraint); - -ConstraintBearing::ConstraintBearing() -{ - ADD_PROPERTY_TYPE(Location,(0),"ConstraintBearing",(App::PropertyType)(App::Prop_None), - "Element giving axial location of constraint"); - ADD_PROPERTY(Dist,(0.0)); - ADD_PROPERTY(AxialFree,(0)); - ADD_PROPERTY(Radius,(0.0)); - ADD_PROPERTY(Height,(0.0)); - ADD_PROPERTY_TYPE(BasePoint,(Base::Vector3d(0,0,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Base point of cylindrical bearing seat"); - ADD_PROPERTY_TYPE(Axis,(Base::Vector3d(0,1,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Axis of bearing seat"); -} - -App::DocumentObjectExecReturn *ConstraintBearing::execute(void) -{ - return Constraint::execute(); -} - -void ConstraintBearing::onChanged(const App::Property* prop) -{ - //Base::Console().Error("ConstraintBearing: onChanged %s\n", prop->getName()); - // Note: If we call this at the end, then the symbol ist not oriented correctly initially - // because the NormalDirection has not been calculated yet - Constraint::onChanged(prop); - - if (prop == &References) { - // Find data of cylinder - double radius, height; - Base::Vector3d base, axis; - if (!getCylinder(radius, height, base, axis)) - return; - Radius.setValue(radius); - Axis.setValue(axis); - Height.setValue(height); - // Update base point - base = base + axis * height/2; - if (Location.getValue() != NULL) { - base = getBasePoint(base, axis, Location, Dist.getValue()); - } - BasePoint.setValue(base); - BasePoint.touch(); // This triggers ViewProvider::updateData() - } else if ((prop == &Location) || (prop == &Dist)) { - App::DocumentObject* obj = Location.getValue(); - std::vector names = Location.getSubValues(); - if (names.size() == 0) { - return; - } - std::string subName = names.front(); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape sh = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (sh.ShapeType() == TopAbs_FACE) { - BRepAdaptor_Surface surface(TopoDS::Face(sh)); - if (surface.GetType() != GeomAbs_Plane) { - return; // "Location must be a planar face or linear edge" - } - } else if (sh.ShapeType() == TopAbs_EDGE) { - BRepAdaptor_Curve line(TopoDS::Edge(sh)); - if (line.GetType() != GeomAbs_Line) { - return; // "Location must be a planar face or linear edge" - } - } - - double radius, height; - Base::Vector3d base, axis; - if (!getCylinder(radius, height, base, axis)) - return; - base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue()); - BasePoint.setValue(base); - BasePoint.touch(); - } -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintBearing.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintBearing, Fem::Constraint); + +ConstraintBearing::ConstraintBearing() +{ + ADD_PROPERTY_TYPE(Location,(0),"ConstraintBearing",(App::PropertyType)(App::Prop_None), + "Element giving axial location of constraint"); + ADD_PROPERTY(Dist,(0.0)); + ADD_PROPERTY(AxialFree,(0)); + ADD_PROPERTY(Radius,(0.0)); + ADD_PROPERTY(Height,(0.0)); + ADD_PROPERTY_TYPE(BasePoint,(Base::Vector3d(0,0,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Base point of cylindrical bearing seat"); + ADD_PROPERTY_TYPE(Axis,(Base::Vector3d(0,1,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Axis of bearing seat"); +} + +App::DocumentObjectExecReturn *ConstraintBearing::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintBearing::onChanged(const App::Property* prop) +{ + //Base::Console().Error("ConstraintBearing: onChanged %s\n", prop->getName()); + // Note: If we call this at the end, then the symbol ist not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + // Find data of cylinder + double radius, height; + Base::Vector3d base, axis; + if (!getCylinder(radius, height, base, axis)) + return; + Radius.setValue(radius); + Axis.setValue(axis); + Height.setValue(height); + // Update base point + base = base + axis * height/2; + if (Location.getValue() != NULL) { + base = getBasePoint(base, axis, Location, Dist.getValue()); + } + BasePoint.setValue(base); + BasePoint.touch(); // This triggers ViewProvider::updateData() + } else if ((prop == &Location) || (prop == &Dist)) { + App::DocumentObject* obj = Location.getValue(); + std::vector names = Location.getSubValues(); + if (names.size() == 0) { + return; + } + std::string subName = names.front(); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape sh = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (sh.ShapeType() == TopAbs_FACE) { + BRepAdaptor_Surface surface(TopoDS::Face(sh)); + if (surface.GetType() != GeomAbs_Plane) { + return; // "Location must be a planar face or linear edge" + } + } else if (sh.ShapeType() == TopAbs_EDGE) { + BRepAdaptor_Curve line(TopoDS::Edge(sh)); + if (line.GetType() != GeomAbs_Line) { + return; // "Location must be a planar face or linear edge" + } + } + + double radius, height; + Base::Vector3d base, axis; + if (!getCylinder(radius, height, base, axis)) + return; + base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue()); + BasePoint.setValue(base); + BasePoint.touch(); + } +} diff --git a/src/Mod/Fem/App/FemConstraintBearing.h b/src/Mod/Fem/App/FemConstraintBearing.h index 66fcd0e070ba..93a0dc2b6e38 100644 --- a/src/Mod/Fem/App/FemConstraintBearing.h +++ b/src/Mod/Fem/App/FemConstraintBearing.h @@ -1,71 +1,71 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINTBEARING_H -#define FEM_CONSTRAINTBEARING_H - -#include -#include -#include - -#include "FemConstraint.h" - -namespace Fem -{ - -class AppFemExport ConstraintBearing : public Fem::Constraint -{ - PROPERTY_HEADER(Fem::ConstraintBearing); - -public: - /// Constructor - ConstraintBearing(void); - - /// Location reference - App::PropertyLinkSub Location; - /// Distance from location reference - App::PropertyFloat Dist; - /// Is the bearing free to move in axial direction? - App::PropertyBool AxialFree; - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyFloat Radius; - App::PropertyFloat Height; - App::PropertyVector BasePoint; - App::PropertyVector Axis; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintBearing"; - } - -protected: - virtual void onChanged(const App::Property* prop); -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINTBEARING_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTBEARING_H +#define FEM_CONSTRAINTBEARING_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintBearing : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintBearing); + +public: + /// Constructor + ConstraintBearing(void); + + /// Location reference + App::PropertyLinkSub Location; + /// Distance from location reference + App::PropertyFloat Dist; + /// Is the bearing free to move in axial direction? + App::PropertyBool AxialFree; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyFloat Radius; + App::PropertyFloat Height; + App::PropertyVector BasePoint; + App::PropertyVector Axis; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintBearing"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTBEARING_H diff --git a/src/Mod/Fem/App/FemConstraintFixed.cpp b/src/Mod/Fem/App/FemConstraintFixed.cpp index afb984694857..d9af420d9c3d 100644 --- a/src/Mod/Fem/App/FemConstraintFixed.cpp +++ b/src/Mod/Fem/App/FemConstraintFixed.cpp @@ -1,86 +1,86 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include "FemConstraintFixed.h" - -#include -#include - -using namespace Fem; - -PROPERTY_SOURCE(Fem::ConstraintFixed, Fem::Constraint); - -ConstraintFixed::ConstraintFixed() -{ - ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Points where symbols are drawn"); - ADD_PROPERTY_TYPE(Normals,(Base::Vector3d()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Normals where symbols are drawn"); - Points.setValues(std::vector()); - Normals.setValues(std::vector()); -} - -App::DocumentObjectExecReturn *ConstraintFixed::execute(void) -{ - return Constraint::execute(); -} - -void ConstraintFixed::onChanged(const App::Property* prop) -{ - // Note: If we call this at the end, then the symbols are not oriented correctly initially - // because the NormalDirection has not been calculated yet - Constraint::onChanged(prop); - - if (prop == &References) { - std::vector points; - std::vector normals; - int scale = 1; //OvG: Enforce use of scale - if (getPoints(points, normals, &scale)) { - Points.setValues(points); - Normals.setValues(normals); - Scale.setValue(scale); //OvG: Scale - Points.touch(); // This triggers ViewProvider::updateData() - } - } -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintFixed.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintFixed, Fem::Constraint); + +ConstraintFixed::ConstraintFixed() +{ + ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Points where symbols are drawn"); + ADD_PROPERTY_TYPE(Normals,(Base::Vector3d()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Normals where symbols are drawn"); + Points.setValues(std::vector()); + Normals.setValues(std::vector()); +} + +App::DocumentObjectExecReturn *ConstraintFixed::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintFixed::onChanged(const App::Property* prop) +{ + // Note: If we call this at the end, then the symbols are not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + std::vector points; + std::vector normals; + int scale = 1; //OvG: Enforce use of scale + if (getPoints(points, normals, &scale)) { + Points.setValues(points); + Normals.setValues(normals); + Scale.setValue(scale); //OvG: Scale + Points.touch(); // This triggers ViewProvider::updateData() + } + } +} diff --git a/src/Mod/Fem/App/FemConstraintFixed.h b/src/Mod/Fem/App/FemConstraintFixed.h index 0294fbdaa310..53d0dc752b2c 100644 --- a/src/Mod/Fem/App/FemConstraintFixed.h +++ b/src/Mod/Fem/App/FemConstraintFixed.h @@ -1,63 +1,63 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINTFIXED_H -#define FEM_CONSTRAINTFIXED_H - -#include -#include -#include - -#include "FemConstraint.h" - -namespace Fem -{ - -class AppFemExport ConstraintFixed : public Fem::Constraint -{ - PROPERTY_HEADER(Fem::ConstraintFixed); - -public: - /// Constructor - ConstraintFixed(void); - - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyVectorList Points; - App::PropertyVectorList Normals; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintFixed"; - } - -protected: - virtual void onChanged(const App::Property* prop); -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINTFIXED_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTFIXED_H +#define FEM_CONSTRAINTFIXED_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintFixed : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintFixed); + +public: + /// Constructor + ConstraintFixed(void); + + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVectorList Points; + App::PropertyVectorList Normals; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintFixed"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTFIXED_H diff --git a/src/Mod/Fem/App/FemConstraintForce.cpp b/src/Mod/Fem/App/FemConstraintForce.cpp index a0a91e3d33a9..47e92db563e6 100644 --- a/src/Mod/Fem/App/FemConstraintForce.cpp +++ b/src/Mod/Fem/App/FemConstraintForce.cpp @@ -1,109 +1,109 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#include -#include -#include -#include -#include -#include -#endif - -#include "FemConstraintForce.h" - -#include -#include - -using namespace Fem; - -PROPERTY_SOURCE(Fem::ConstraintForce, Fem::Constraint); - -ConstraintForce::ConstraintForce() -{ - ADD_PROPERTY(Force,(0.0)); - ADD_PROPERTY_TYPE(Direction,(0),"ConstraintForce",(App::PropertyType)(App::Prop_None), - "Element giving direction of constraint"); - ADD_PROPERTY(Reversed,(0)); - ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Points where arrows are drawn"); - ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3d(0,0,1)),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Direction of arrows"); - naturalDirectionVector = Base::Vector3d(0,0,0); // by default use the null vector to indication an invalid value - Points.setValues(std::vector()); -} - -App::DocumentObjectExecReturn *ConstraintForce::execute(void) -{ - return Constraint::execute(); -} - -void ConstraintForce::onChanged(const App::Property* prop) -{ - // Note: If we call this at the end, then the arrows are not oriented correctly initially - // because the NormalDirection has not been calculated yet - Constraint::onChanged(prop); - - if (prop == &References) { - std::vector points; - std::vector normals; - int scale = 1; //OvG: Enforce use of scale - if (getPoints(points, normals, &scale)) { - Points.setValues(points); // We don't use the normals because all arrows should have the same direction - Scale.setValue(scale); //OvG Scale - Points.touch(); - } - } else if (prop == &Direction) { - Base::Vector3d direction = getDirection(Direction); - if (direction.Length() < Precision::Confusion()) - return; - naturalDirectionVector = direction; - if (Reversed.getValue()) - direction = -direction; - DirectionVector.setValue(direction); - } else if (prop == &Reversed) { - // if the direction is invalid try to compute it again - if (naturalDirectionVector.Length() < Precision::Confusion()) { - naturalDirectionVector = getDirection(Direction); - } - if (naturalDirectionVector.Length() >= Precision::Confusion()) { - if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) { - DirectionVector.setValue(-naturalDirectionVector); - } else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) { - DirectionVector.setValue(naturalDirectionVector); - } - } - } else if (prop == &NormalDirection) { - // Set a default direction if no direction reference has been given - if (Direction.getValue() == NULL) { - Base::Vector3d direction = NormalDirection.getValue(); - if (Reversed.getValue()) - direction = -direction; - DirectionVector.setValue(direction); - naturalDirectionVector = direction; - } - } -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintForce.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintForce, Fem::Constraint); + +ConstraintForce::ConstraintForce() +{ + ADD_PROPERTY(Force,(0.0)); + ADD_PROPERTY_TYPE(Direction,(0),"ConstraintForce",(App::PropertyType)(App::Prop_None), + "Element giving direction of constraint"); + ADD_PROPERTY(Reversed,(0)); + ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Points where arrows are drawn"); + ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3d(0,0,1)),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Direction of arrows"); + naturalDirectionVector = Base::Vector3d(0,0,0); // by default use the null vector to indication an invalid value + Points.setValues(std::vector()); +} + +App::DocumentObjectExecReturn *ConstraintForce::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintForce::onChanged(const App::Property* prop) +{ + // Note: If we call this at the end, then the arrows are not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + std::vector points; + std::vector normals; + int scale = 1; //OvG: Enforce use of scale + if (getPoints(points, normals, &scale)) { + Points.setValues(points); // We don't use the normals because all arrows should have the same direction + Scale.setValue(scale); //OvG Scale + Points.touch(); + } + } else if (prop == &Direction) { + Base::Vector3d direction = getDirection(Direction); + if (direction.Length() < Precision::Confusion()) + return; + naturalDirectionVector = direction; + if (Reversed.getValue()) + direction = -direction; + DirectionVector.setValue(direction); + } else if (prop == &Reversed) { + // if the direction is invalid try to compute it again + if (naturalDirectionVector.Length() < Precision::Confusion()) { + naturalDirectionVector = getDirection(Direction); + } + if (naturalDirectionVector.Length() >= Precision::Confusion()) { + if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) { + DirectionVector.setValue(-naturalDirectionVector); + } else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) { + DirectionVector.setValue(naturalDirectionVector); + } + } + } else if (prop == &NormalDirection) { + // Set a default direction if no direction reference has been given + if (Direction.getValue() == NULL) { + Base::Vector3d direction = NormalDirection.getValue(); + if (Reversed.getValue()) + direction = -direction; + DirectionVector.setValue(direction); + naturalDirectionVector = direction; + } + } +} diff --git a/src/Mod/Fem/App/FemConstraintForce.h b/src/Mod/Fem/App/FemConstraintForce.h index 9d7f2b08e39c..61f06e33510f 100644 --- a/src/Mod/Fem/App/FemConstraintForce.h +++ b/src/Mod/Fem/App/FemConstraintForce.h @@ -1,69 +1,69 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINTFORCE_H -#define FEM_CONSTRAINTFORCE_H - -#include -#include -#include - -#include "FemConstraint.h" - -namespace Fem -{ - -class AppFemExport ConstraintForce : public Fem::Constraint -{ - PROPERTY_HEADER(Fem::ConstraintForce); - -public: - /// Constructor - ConstraintForce(void); - - App::PropertyFloat Force; - App::PropertyLinkSub Direction; - App::PropertyBool Reversed; - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyVectorList Points; - App::PropertyVector DirectionVector; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintForce"; - } - -protected: - virtual void onChanged(const App::Property* prop); - -private: - Base::Vector3d naturalDirectionVector; -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINTFORCE_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTFORCE_H +#define FEM_CONSTRAINTFORCE_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintForce : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintForce); + +public: + /// Constructor + ConstraintForce(void); + + App::PropertyFloat Force; + App::PropertyLinkSub Direction; + App::PropertyBool Reversed; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVectorList Points; + App::PropertyVector DirectionVector; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintForce"; + } + +protected: + virtual void onChanged(const App::Property* prop); + +private: + Base::Vector3d naturalDirectionVector; +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTFORCE_H diff --git a/src/Mod/Fem/App/FemConstraintGear.cpp b/src/Mod/Fem/App/FemConstraintGear.cpp index f9a4306529a9..236ff2199648 100644 --- a/src/Mod/Fem/App/FemConstraintGear.cpp +++ b/src/Mod/Fem/App/FemConstraintGear.cpp @@ -1,86 +1,86 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#include -#include -#include -#include -#include -#include -#endif - -#include "FemConstraintGear.h" - -#include -#include - -using namespace Fem; - -PROPERTY_SOURCE(Fem::ConstraintGear, Fem::ConstraintBearing); - -ConstraintGear::ConstraintGear() -{ - ADD_PROPERTY(Diameter,(100.0)); - ADD_PROPERTY(Force,(1000.0)); - ADD_PROPERTY(ForceAngle,(0.0)); - ADD_PROPERTY_TYPE(Direction,(0),"ConstraintGear",(App::PropertyType)(App::Prop_None), - "Element giving direction of gear force"); - ADD_PROPERTY(Reversed,(0)); - ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3d(1,1,1).Normalize()),"ConstraintGear",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Direction of gear force"); - naturalDirectionVector = Base::Vector3d(1,1,1).Normalize(); -} - -App::DocumentObjectExecReturn *ConstraintGear::execute(void) -{ - return ConstraintBearing::execute(); -} - -void ConstraintGear::onChanged(const App::Property* prop) -{ - ConstraintBearing::onChanged(prop); - - if (prop == &Direction) { - Base::Vector3d direction = getDirection(Direction); - if (direction.Length() < Precision::Confusion()) - return; - naturalDirectionVector = direction; - if (Reversed.getValue()) - direction = -direction; - DirectionVector.setValue(direction); - DirectionVector.touch(); - } else if (prop == &Reversed) { - if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) { - DirectionVector.setValue(-naturalDirectionVector); - DirectionVector.touch(); - } else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) { - DirectionVector.setValue(naturalDirectionVector); - DirectionVector.touch(); - } - } - // The computation for the force angle is simpler in the ViewProvider directly -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintGear.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintGear, Fem::ConstraintBearing); + +ConstraintGear::ConstraintGear() +{ + ADD_PROPERTY(Diameter,(100.0)); + ADD_PROPERTY(Force,(1000.0)); + ADD_PROPERTY(ForceAngle,(0.0)); + ADD_PROPERTY_TYPE(Direction,(0),"ConstraintGear",(App::PropertyType)(App::Prop_None), + "Element giving direction of gear force"); + ADD_PROPERTY(Reversed,(0)); + ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3d(1,1,1).Normalize()),"ConstraintGear",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Direction of gear force"); + naturalDirectionVector = Base::Vector3d(1,1,1).Normalize(); +} + +App::DocumentObjectExecReturn *ConstraintGear::execute(void) +{ + return ConstraintBearing::execute(); +} + +void ConstraintGear::onChanged(const App::Property* prop) +{ + ConstraintBearing::onChanged(prop); + + if (prop == &Direction) { + Base::Vector3d direction = getDirection(Direction); + if (direction.Length() < Precision::Confusion()) + return; + naturalDirectionVector = direction; + if (Reversed.getValue()) + direction = -direction; + DirectionVector.setValue(direction); + DirectionVector.touch(); + } else if (prop == &Reversed) { + if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) { + DirectionVector.setValue(-naturalDirectionVector); + DirectionVector.touch(); + } else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) { + DirectionVector.setValue(naturalDirectionVector); + DirectionVector.touch(); + } + } + // The computation for the force angle is simpler in the ViewProvider directly +} diff --git a/src/Mod/Fem/App/FemConstraintGear.h b/src/Mod/Fem/App/FemConstraintGear.h index 1e6384659fec..9b5ec240cc02 100644 --- a/src/Mod/Fem/App/FemConstraintGear.h +++ b/src/Mod/Fem/App/FemConstraintGear.h @@ -1,70 +1,70 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINTGear_H -#define FEM_CONSTRAINTGear_H - -#include -#include -#include - -#include "FemConstraintBearing.h" - -namespace Fem -{ - -class AppFemExport ConstraintGear : public Fem::ConstraintBearing -{ - PROPERTY_HEADER(Fem::ConstraintGear); - -public: - /// Constructor - ConstraintGear(void); - - App::PropertyFloat Diameter; - App::PropertyFloat Force; - App::PropertyFloat ForceAngle; - App::PropertyLinkSub Direction; - App::PropertyBool Reversed; - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyVector DirectionVector; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintGear"; - } - -protected: - virtual void onChanged(const App::Property* prop); - -private: - Base::Vector3d naturalDirectionVector; -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINTGear_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTGear_H +#define FEM_CONSTRAINTGear_H + +#include +#include +#include + +#include "FemConstraintBearing.h" + +namespace Fem +{ + +class AppFemExport ConstraintGear : public Fem::ConstraintBearing +{ + PROPERTY_HEADER(Fem::ConstraintGear); + +public: + /// Constructor + ConstraintGear(void); + + App::PropertyFloat Diameter; + App::PropertyFloat Force; + App::PropertyFloat ForceAngle; + App::PropertyLinkSub Direction; + App::PropertyBool Reversed; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVector DirectionVector; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintGear"; + } + +protected: + virtual void onChanged(const App::Property* prop); + +private: + Base::Vector3d naturalDirectionVector; +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTGear_H diff --git a/src/Mod/Fem/App/FemConstraintPulley.cpp b/src/Mod/Fem/App/FemConstraintPulley.cpp index 4c933b4d9f3e..1197dae78266 100644 --- a/src/Mod/Fem/App/FemConstraintPulley.cpp +++ b/src/Mod/Fem/App/FemConstraintPulley.cpp @@ -1,98 +1,98 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#include -#include -#include -#include -#include -#include -#endif - -#include "FemConstraintPulley.h" - -#include -#include - -using namespace Fem; - -PROPERTY_SOURCE(Fem::ConstraintPulley, Fem::ConstraintGear); - -ConstraintPulley::ConstraintPulley() -{ - ADD_PROPERTY(OtherDiameter,(100.0)); - ADD_PROPERTY(CenterDistance,(500.0)); - ADD_PROPERTY(IsDriven,(0)); - ADD_PROPERTY(TensionForce,(0.0)); - - ADD_PROPERTY_TYPE(BeltAngle,(0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Angle of belt forces"); - ADD_PROPERTY_TYPE(BeltForce1,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "First belt force"); - ADD_PROPERTY_TYPE(BeltForce2,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), - "Second belt force"); - ForceAngle.setValue(00.0); - Diameter.setValue(300.0); - // calculate initial values of read-only properties - onChanged(&Force); -} - -App::DocumentObjectExecReturn *ConstraintPulley::execute(void) -{ - return ConstraintBearing::execute(); -} - -void ConstraintPulley::onChanged(const App::Property* prop) -{ - ConstraintGear::onChanged(prop); - - if ((prop == &Diameter) || (prop == &OtherDiameter) || (prop == &CenterDistance)) { - if (CenterDistance.getValue() > Precision::Confusion()) { - BeltAngle.setValue(asin((Diameter.getValue() - OtherDiameter.getValue())/2/CenterDistance.getValue())); - BeltAngle.touch(); - } - } else if ((prop == &Force) || (prop == &TensionForce) || (prop == &IsDriven)) { - double radius = Diameter.getValue() / 2.0; - if (radius < Precision::Confusion()) - return; - double force = Force.getValue() / (radius/1000); - if (fabs(force) < Precision::Confusion()) - return; - bool neg = (force < 0.0); - if (neg) - force *= -1.0; - - if ((IsDriven.getValue() && neg) || (!IsDriven.getValue() && !neg)) { - BeltForce1.setValue(force + TensionForce.getValue()); - BeltForce2.setValue(TensionForce.getValue()); - } else { - BeltForce2.setValue(force + TensionForce.getValue()); - BeltForce1.setValue(TensionForce.getValue()); - } - BeltForce1.touch(); - } -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintPulley.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintPulley, Fem::ConstraintGear); + +ConstraintPulley::ConstraintPulley() +{ + ADD_PROPERTY(OtherDiameter,(100.0)); + ADD_PROPERTY(CenterDistance,(500.0)); + ADD_PROPERTY(IsDriven,(0)); + ADD_PROPERTY(TensionForce,(0.0)); + + ADD_PROPERTY_TYPE(BeltAngle,(0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Angle of belt forces"); + ADD_PROPERTY_TYPE(BeltForce1,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "First belt force"); + ADD_PROPERTY_TYPE(BeltForce2,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Second belt force"); + ForceAngle.setValue(00.0); + Diameter.setValue(300.0); + // calculate initial values of read-only properties + onChanged(&Force); +} + +App::DocumentObjectExecReturn *ConstraintPulley::execute(void) +{ + return ConstraintBearing::execute(); +} + +void ConstraintPulley::onChanged(const App::Property* prop) +{ + ConstraintGear::onChanged(prop); + + if ((prop == &Diameter) || (prop == &OtherDiameter) || (prop == &CenterDistance)) { + if (CenterDistance.getValue() > Precision::Confusion()) { + BeltAngle.setValue(asin((Diameter.getValue() - OtherDiameter.getValue())/2/CenterDistance.getValue())); + BeltAngle.touch(); + } + } else if ((prop == &Force) || (prop == &TensionForce) || (prop == &IsDriven)) { + double radius = Diameter.getValue() / 2.0; + if (radius < Precision::Confusion()) + return; + double force = Force.getValue() / (radius/1000); + if (fabs(force) < Precision::Confusion()) + return; + bool neg = (force < 0.0); + if (neg) + force *= -1.0; + + if ((IsDriven.getValue() && neg) || (!IsDriven.getValue() && !neg)) { + BeltForce1.setValue(force + TensionForce.getValue()); + BeltForce2.setValue(TensionForce.getValue()); + } else { + BeltForce2.setValue(force + TensionForce.getValue()); + BeltForce1.setValue(TensionForce.getValue()); + } + BeltForce1.touch(); + } +} diff --git a/src/Mod/Fem/App/FemConstraintPulley.h b/src/Mod/Fem/App/FemConstraintPulley.h index 611652570a48..9d7707247092 100644 --- a/src/Mod/Fem/App/FemConstraintPulley.h +++ b/src/Mod/Fem/App/FemConstraintPulley.h @@ -1,73 +1,73 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_CONSTRAINTPulley_H -#define FEM_CONSTRAINTPulley_H - -#include -#include -#include - -#include "FemConstraintGear.h" - -namespace Fem -{ - -class AppFemExport ConstraintPulley : public Fem::ConstraintGear -{ - PROPERTY_HEADER(Fem::ConstraintPulley); - -public: - /// Constructor - ConstraintPulley(void); - - /// Other pulley diameter - App::PropertyFloat OtherDiameter; - /// Center distance between the pulleys - App::PropertyFloat CenterDistance; - /// Driven pulley or driving pulley? - App::PropertyBool IsDriven; - /// Belt tension force - App::PropertyFloat TensionForce; - // Read-only (calculated values). These trigger changes in the ViewProvider - App::PropertyFloat BeltAngle; - App::PropertyFloat BeltForce1; - App::PropertyFloat BeltForce2; - - /// recalculate the object - virtual App::DocumentObjectExecReturn *execute(void); - - /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintPulley"; - } - -protected: - virtual void onChanged(const App::Property* prop); - -}; - -} //namespace Fem - - -#endif // FEM_CONSTRAINTPulley_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTPulley_H +#define FEM_CONSTRAINTPulley_H + +#include +#include +#include + +#include "FemConstraintGear.h" + +namespace Fem +{ + +class AppFemExport ConstraintPulley : public Fem::ConstraintGear +{ + PROPERTY_HEADER(Fem::ConstraintPulley); + +public: + /// Constructor + ConstraintPulley(void); + + /// Other pulley diameter + App::PropertyFloat OtherDiameter; + /// Center distance between the pulleys + App::PropertyFloat CenterDistance; + /// Driven pulley or driving pulley? + App::PropertyBool IsDriven; + /// Belt tension force + App::PropertyFloat TensionForce; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyFloat BeltAngle; + App::PropertyFloat BeltForce1; + App::PropertyFloat BeltForce2; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintPulley"; + } + +protected: + virtual void onChanged(const App::Property* prop); + +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTPulley_H diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 873ab77e260a..49fbc9f8129c 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -1,1414 +1,1414 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "FemMesh.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include - -//to simplify parsing input files we use the boost lib -#include - - -using namespace Fem; -using namespace Base; -using namespace boost; - -static int StatCount = 0; - -TYPESYSTEM_SOURCE(Fem::FemMesh , Base::Persistence); - -FemMesh::FemMesh() -{ - //Base::Console().Log("FemMesh::FemMesh():%p (id=%i)\n",this,StatCount); - myGen = new SMESH_Gen(); - // create a mesh allways with new StudyId to avoid overlapping destruction - myMesh = myGen->CreateMesh(StatCount++,false); - -} - -FemMesh::FemMesh(const FemMesh& mesh) -{ - //Base::Console().Log("FemMesh::FemMesh(mesh):%p (id=%i)\n",this,StatCount); - myGen = new SMESH_Gen(); - myMesh = myGen->CreateMesh(StatCount++,false); - copyMeshData(mesh); -} - -FemMesh::~FemMesh() -{ - //Base::Console().Log("FemMesh::~FemMesh():%p\n",this); - - TopoDS_Shape aNull; - myMesh->ShapeToMesh(aNull); - myMesh->Clear(); - //myMesh->ClearLog(); - delete myMesh; -#if defined(__GNUC__) - delete myGen; // crashes with MSVC -#endif -} - -FemMesh &FemMesh::operator=(const FemMesh& mesh) -{ - if (this != &mesh) { - copyMeshData(mesh); - } - return *this; -} - -void FemMesh::copyMeshData(const FemMesh& mesh) -{ - //const SMDS_MeshInfo& info = mesh.myMesh->GetMeshDS()->GetMeshInfo(); - //int numPoly = info.NbPolygons(); - //int numVolu = info.NbVolumes(); - //int numTetr = info.NbTetras(); - //int numHexa = info.NbHexas(); - //int numPyrd = info.NbPyramids(); - //int numPris = info.NbPrisms(); - //int numHedr = info.NbPolyhedrons(); - - _Mtrx = mesh._Mtrx; - - SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); - meshds->ClearMesh(); - - SMDS_NodeIteratorPtr aNodeIter = mesh.myMesh->GetMeshDS()->nodesIterator(); - for (;aNodeIter->more();) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - meshds->AddNodeWithID(aNode->X(),aNode->Y(),aNode->Z(), aNode->GetID()); - } - - SMDS_EdgeIteratorPtr aEdgeIter = mesh.myMesh->GetMeshDS()->edgesIterator(); - for (;aEdgeIter->more();) { - const SMDS_MeshEdge* aEdge = aEdgeIter->next(); - meshds->AddEdgeWithID(aEdge->GetNode(0), aEdge->GetNode(1), aEdge->GetID()); - } - - SMDS_FaceIteratorPtr aFaceIter = mesh.myMesh->GetMeshDS()->facesIterator(); - for (;aFaceIter->more();) { - const SMDS_MeshFace* aFace = aFaceIter->next(); - switch (aFace->NbNodes()) { - case 3: - meshds->AddFaceWithID(aFace->GetNode(0), - aFace->GetNode(1), - aFace->GetNode(2), - aFace->GetID()); - break; - case 4: - meshds->AddFaceWithID(aFace->GetNode(0), - aFace->GetNode(1), - aFace->GetNode(2), - aFace->GetNode(3), - aFace->GetID()); - break; - case 6: - meshds->AddFaceWithID(aFace->GetNode(0), - aFace->GetNode(1), - aFace->GetNode(2), - aFace->GetNode(3), - aFace->GetNode(4), - aFace->GetNode(5), - aFace->GetID()); - break; - case 8: - meshds->AddFaceWithID(aFace->GetNode(0), - aFace->GetNode(1), - aFace->GetNode(2), - aFace->GetNode(3), - aFace->GetNode(4), - aFace->GetNode(5), - aFace->GetNode(6), - aFace->GetNode(7), - aFace->GetID()); - break; - default: - { - std::vector aNodes; - for (int i=0; aFace->NbNodes(); i++) - aNodes.push_back(aFace->GetNode(0)); - meshds->AddPolygonalFaceWithID(aNodes, aFace->GetID()); - } - break; - } - } - - SMDS_VolumeIteratorPtr aVolIter = mesh.myMesh->GetMeshDS()->volumesIterator(); - for (;aVolIter->more();) { - const SMDS_MeshVolume* aVol = aVolIter->next(); - switch (aVol->NbNodes()) { - case 4: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetID()); - break; - case 5: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetID()); - break; - case 6: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetID()); - break; - case 8: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetNode(6), - aVol->GetNode(7), - aVol->GetID()); - break; - case 10: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetNode(6), - aVol->GetNode(7), - aVol->GetNode(8), - aVol->GetNode(9), - aVol->GetID()); - break; - case 13: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetNode(6), - aVol->GetNode(7), - aVol->GetNode(8), - aVol->GetNode(9), - aVol->GetNode(10), - aVol->GetNode(11), - aVol->GetNode(12), - aVol->GetID()); - break; - case 15: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetNode(6), - aVol->GetNode(7), - aVol->GetNode(8), - aVol->GetNode(9), - aVol->GetNode(10), - aVol->GetNode(11), - aVol->GetNode(12), - aVol->GetNode(13), - aVol->GetNode(14), - aVol->GetID()); - break; - case 20: - meshds->AddVolumeWithID(aVol->GetNode(0), - aVol->GetNode(1), - aVol->GetNode(2), - aVol->GetNode(3), - aVol->GetNode(4), - aVol->GetNode(5), - aVol->GetNode(6), - aVol->GetNode(7), - aVol->GetNode(8), - aVol->GetNode(9), - aVol->GetNode(10), - aVol->GetNode(11), - aVol->GetNode(12), - aVol->GetNode(13), - aVol->GetNode(14), - aVol->GetNode(15), - aVol->GetNode(16), - aVol->GetNode(17), - aVol->GetNode(18), - aVol->GetNode(19), - aVol->GetID()); - break; - default: - { - if (aVol->IsPoly()) { - const SMDS_PolyhedralVolumeOfNodes* aPolyVol = dynamic_cast(aVol); - if (!aPolyVol) break; - std::vector aNodes; - for (int i=0; iNbNodes(); i++) - aNodes.push_back(aPolyVol->GetNode(i)); - meshds->AddPolyhedralVolumeWithID(aNodes, - aPolyVol->GetQuanities(), aPolyVol->GetID()); - } - } - break; - } - } -} - -const SMESH_Mesh* FemMesh::getSMesh() const -{ - return myMesh; -} - -SMESH_Mesh* FemMesh::getSMesh() -{ - return myMesh; -} - - -SMESH_Gen * FemMesh::getGenerator() -{ - return myGen; -} - -void FemMesh::addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp) -{ - myMesh->AddHypothesis(aSubShape, hyp->GetID()); - SMESH_HypothesisPtr ptr(hyp); - hypoth.push_back(ptr); -} - -void FemMesh::setStanardHypotheses() -{ - if (!hypoth.empty()) - return; - int hyp=0; - SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, myGen)); - static_cast(len.get())->SetLength(1.0); - hypoth.push_back(len); - - SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen)); - static_cast(loc.get())->SetLength(1.0); - hypoth.push_back(loc); - - SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen)); - static_cast(area.get())->SetMaxArea(1.0); - hypoth.push_back(area); - - SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen)); - static_cast(segm.get())->SetNumberOfSegments(1); - hypoth.push_back(segm); - - SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen)); - static_cast(defl.get())->SetDeflection(0.01); - hypoth.push_back(defl); - - SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, myGen)); - hypoth.push_back(reg); - - //SMESH_HypothesisPtr sel(new StdMeshers_StartEndLength(hyp++, 1, myGen)); - //static_cast(sel.get())->SetLength(1.0, true); - //hypoth.push_back(sel); - - SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++,1,myGen)); - hypoth.push_back(qdp); - - SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++,1,myGen)); - hypoth.push_back(q2d); - - // Apply hypothesis - for (int i=0; iAddHypothesis(myMesh->GetShapeToMesh(), i); -} - -void FemMesh::compute() -{ - myGen->Compute(*myMesh, myMesh->GetShapeToMesh()); -} - -std::set FemMesh::getSurfaceNodes(long ElemId, short FaceId, float Angle) const -{ - std::set result; - //const SMESHDS_Mesh* data = myMesh->GetMeshDS(); - - //const SMDS_MeshElement * element = data->FindElement(ElemId); - //int fNbr = element->NbFaces(); - //element-> - - return result; -} - -/*! That function returns map containing volume ID and face ID. - */ -std::list > FemMesh::getVolumesByFace(const TopoDS_Face &face) const -{ - std::list > result; - std::set nodes_on_face = getNodesByFace(face); - - SMDS_VolumeIteratorPtr vol_iter = myMesh->GetMeshDS()->volumesIterator(); - while (vol_iter->more()) { - const SMDS_MeshVolume* vol = vol_iter->next(); - SMDS_ElemIteratorPtr face_iter = vol->facesIterator(); - - while (face_iter->more()) { - const SMDS_MeshFace* face = static_cast(face_iter->next()); - int numNodes = face->NbNodes(); - - std::set face_nodes; - for (int i=0; iGetNode(i)->GetID()); - } - - std::vector element_face_nodes; - std::set_intersection(nodes_on_face.begin(), nodes_on_face.end(), face_nodes.begin(), face_nodes.end(), - std::back_insert_iterator >(element_face_nodes)); - - // For curved faces it is possible that a volume contributes more than one face - if (element_face_nodes.size() == static_cast(numNodes)) { - result.push_back(std::make_pair(vol->GetID(), face->GetID())); - } - } - } - - result.sort(); - return result; -} - -/*! That function returns map containing volume ID and face number - * as per CalculiX definition for tetrahedral elements. See CalculiX - * documentation for the details. - */ -std::map FemMesh::getccxVolumesByFace(const TopoDS_Face &face) const -{ - std::map result; - std::set nodes_on_face = getNodesByFace(face); - - static std::map > elem_order; - if (elem_order.empty()) { - std::vector c3d4 = boost::assign::list_of(1)(0)(2)(3); - std::vector c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9); - - elem_order.insert(std::make_pair(c3d4.size(), c3d4)); - elem_order.insert(std::make_pair(c3d10.size(), c3d10)); - } - - SMDS_VolumeIteratorPtr vol_iter = myMesh->GetMeshDS()->volumesIterator(); - std::set element_nodes; - int num_of_nodes; - while (vol_iter->more()) { - const SMDS_MeshVolume* vol = vol_iter->next(); - num_of_nodes = vol->NbNodes(); - std::pair > apair; - apair.first = vol->GetID(); - - std::map >::iterator it = elem_order.find(num_of_nodes); - if (it != elem_order.end()) { - const std::vector& order = it->second; - for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) { - int vid = vol->GetNode(*jt)->GetID(); - apair.second.push_back(vid); - } - } - - // Get volume nodes on face - std::vector element_face_nodes; - std::set element_nodes; - element_nodes.insert(apair.second.begin(), apair.second.end()); - std::set_intersection(nodes_on_face.begin(), nodes_on_face.end(), element_nodes.begin(), element_nodes.end(), - std::back_insert_iterator >(element_face_nodes)); - - if ((element_face_nodes.size() == 3 && num_of_nodes == 4) || - (element_face_nodes.size() == 6 && num_of_nodes == 10)) { - int missing_node = 0; - for (int i=0; i<4; i++) { - // search for the ID of the volume which is not part of 'element_face_nodes' - if (std::find(element_face_nodes.begin(), element_face_nodes.end(), apair.second[i]) == element_face_nodes.end()) { - missing_node = i + 1; - break; - } - } - /* for tetrahedral elements as per CalculiX definition: - Face 1: 1-2-3, missing point 4 means it's face P1 - Face 2: 1-4-2, missing point 3 means it's face P2 - Face 3: 2-4-3, missing point 1 means it's face P3 - Face 4: 3-4-1, missing point 2 means it's face P4 */ - int face_ccx = 0; - switch (missing_node) { - case 1: - face_ccx = 3; - break; - case 2: - face_ccx = 4; - break; - case 3: - face_ccx = 2; - break; - case 4: - face_ccx = 1; - break; - default: - assert(false); // should never happen - break; - } - result[apair.first] = face_ccx; - } - } - - return result; -} - -std::set FemMesh::getNodesBySolid(const TopoDS_Solid &solid) const -{ - std::set result; - - Bnd_Box box; - BRepBndLib::Add(solid, box); - // limit where the mesh node belongs to the solid: - double limit = box.SquareExtent()/10000.0; - //double limit = BRep_Tool::Tolerance(solid); // does not compile --> no matching function for call to 'BRep_Tool::Tolerance(const TopoDS_Solid&)' - box.Enlarge(limit); - - // get the current transform of the FemMesh - const Base::Matrix4D Mtrx(getTransform()); - - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - // Apply the matrix to hold the BoundBox in absolute space. - vec = Mtrx * vec; - - if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { - // create a vertex - BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); - TopoDS_Shape s = aBuilder.Vertex(); - // measure distance - BRepExtrema_DistShapeShape measure(solid,s); - measure.Perform(); - if (!measure.IsDone() || measure.NbSolution() < 1) - continue; - - if (measure.Value() < limit) - result.insert(aNode->GetID()); - } - } - - return result; -} - -std::set FemMesh::getNodesByFace(const TopoDS_Face &face) const -{ - std::set result; - - Bnd_Box box; - BRepBndLib::Add(face, box); - // limit where the mesh node belongs to the face: - double limit = BRep_Tool::Tolerance(face); - box.Enlarge(limit); - - // get the current transform of the FemMesh - const Base::Matrix4D Mtrx(getTransform()); - - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - // Apply the matrix to hold the BoundBox in absolute space. - vec = Mtrx * vec; - - if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { - // create a vertex - BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); - TopoDS_Shape s = aBuilder.Vertex(); - // measure distance - BRepExtrema_DistShapeShape measure(face,s); - measure.Perform(); - if (!measure.IsDone() || measure.NbSolution() < 1) - continue; - - if (measure.Value() < limit) - result.insert(aNode->GetID()); - } - } - - return result; -} - -std::set FemMesh::getNodesByEdge(const TopoDS_Edge &edge) const -{ - std::set result; - - Bnd_Box box; - BRepBndLib::Add(edge, box); - // limit where the mesh node belongs to the edge: - double limit = BRep_Tool::Tolerance(edge); - box.Enlarge(limit); - - // get the current transform of the FemMesh - const Base::Matrix4D Mtrx(getTransform()); - - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - // Apply the matrix to hold the BoundBox in absolute space. - vec = Mtrx * vec; - - if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { - // create a vertex - BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); - TopoDS_Shape s = aBuilder.Vertex(); - // measure distance - BRepExtrema_DistShapeShape measure(edge,s); - measure.Perform(); - if (!measure.IsDone() || measure.NbSolution() < 1) - continue; - - if (measure.Value() < limit) - result.insert(aNode->GetID()); - } - } - - return result; -} - -std::set FemMesh::getNodesByVertex(const TopoDS_Vertex &vertex) const -{ - std::set result; - - double limit = BRep_Tool::Tolerance(vertex); - limit *= limit; // use square to improve speed - gp_Pnt pnt = BRep_Tool::Pnt(vertex); - Base::Vector3d node(pnt.X(), pnt.Y(), pnt.Z()); - - // get the current transform of the FemMesh - const Base::Matrix4D Mtrx(getTransform()); - - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - vec = Mtrx * vec; - - if (Base::DistanceP2(node, vec) <= limit) { - result.insert(aNode->GetID()); - } - } - - return result; -} - -std::list FemMesh::getElementNodes(int id) const -{ - std::list result; - const SMDS_MeshElement* elem = myMesh->GetMeshDS()->FindElement(id); - if (elem) { - for (int i = 0; i < elem->NbNodes(); i++) - result.push_back(elem->GetNode(i)->GetID()); - } - return result; -} - -void FemMesh::readNastran(const std::string &Filename) -{ - Base::TimeInfo Start; - Base::Console().Log("Start: FemMesh::readNastran() =================================\n"); - - _Mtrx = Base::Matrix4D(); - - std::ifstream inputfile; - inputfile.open(Filename.c_str()); - inputfile.seekg(std::ifstream::beg); - std::string line1,line2,temp; - std::vector token_results; - token_results.clear(); - Base::Vector3d current_node; - std::vector vertices; - vertices.clear(); - std::vector nodal_id; - nodal_id.clear(); - std::vector tetra_element; - std::vector > all_elements; - std::vector element_id; - element_id.clear(); - bool nastran_free_format = false; - do - { - std::getline(inputfile,line1); - if (line1.size() == 0) continue; - if (!nastran_free_format && line1.find(",")!= std::string::npos) - nastran_free_format = true; - if (!nastran_free_format && line1.find("GRID*")!= std::string::npos ) //We found a Grid line - { - //Now lets extract the GRID Points = Nodes - //As each GRID Line consists of two subsequent lines we have to - //take care of that as well - std::getline(inputfile,line2); - //Get the Nodal ID - nodal_id.push_back(atoi(line1.substr(8,24).c_str())); - //Extract X Value - current_node.x = atof(line1.substr(40,56).c_str()); - //Extract Y Value - current_node.y = atof(line1.substr(56,72).c_str()); - //Extract Z Value - current_node.z = atof(line2.substr(8,24).c_str()); - - vertices.push_back(current_node); - } - else if (!nastran_free_format && line1.find("CTETRA")!= std::string::npos) - { - tetra_element.clear(); - //Lets extract the elements - //As each Element Line consists of two subsequent lines as well - //we have to take care of that - //At a first step we only extract Quadratic Tetrahedral Elements - std::getline(inputfile,line2); - unsigned int id = atoi(line1.substr(8,16).c_str()); - int offset = 0; - - if(id < 1000000) - offset = 0; - else if (id < 10000000) - offset = 1; - else if (id < 100000000) - offset = 2; - - - element_id.push_back(id); - tetra_element.push_back(atoi(line1.substr(24,32).c_str())); - tetra_element.push_back(atoi(line1.substr(32,40).c_str())); - tetra_element.push_back(atoi(line1.substr(40,48).c_str())); - tetra_element.push_back(atoi(line1.substr(48,56).c_str())); - tetra_element.push_back(atoi(line1.substr(56,64).c_str())); - tetra_element.push_back(atoi(line1.substr(64,72).c_str())); - tetra_element.push_back(atoi(line2.substr(8+offset,16+offset).c_str())); - tetra_element.push_back(atoi(line2.substr(16+offset,24+offset).c_str())); - tetra_element.push_back(atoi(line2.substr(24+offset,32+offset).c_str())); - tetra_element.push_back(atoi(line2.substr(32+offset,40+offset).c_str())); - - all_elements.push_back(tetra_element); - } - else if (nastran_free_format && line1.find("GRID")!= std::string::npos ) //We found a Grid line - { - char_separator sep(","); - tokenizer > tokens(line1, sep); - token_results.assign(tokens.begin(),tokens.end()); - if (token_results.size() < 3) - continue;//Line does not include Nodal coordinates - nodal_id.push_back(atoi(token_results[1].c_str())); - current_node.x = atof(token_results[3].c_str()); - current_node.y = atof(token_results[4].c_str()); - current_node.z = atof(token_results[5].c_str()); - vertices.push_back(current_node); - } - else if (nastran_free_format && line1.find("CTETRA")!= std::string::npos) - { - tetra_element.clear(); - //Lets extract the elements - //As each Element Line consists of two subsequent lines as well - //we have to take care of that - //At a first step we only extract Quadratic Tetrahedral Elements - std::getline(inputfile,line2); - char_separator sep(","); - tokenizer > tokens(line1.append(line2), sep); - token_results.assign(tokens.begin(),tokens.end()); - if (token_results.size() < 11) - continue;//Line does not include enough nodal IDs - element_id.push_back(atoi(token_results[1].c_str())); - tetra_element.push_back(atoi(token_results[3].c_str())); - tetra_element.push_back(atoi(token_results[4].c_str())); - tetra_element.push_back(atoi(token_results[5].c_str())); - tetra_element.push_back(atoi(token_results[6].c_str())); - tetra_element.push_back(atoi(token_results[7].c_str())); - tetra_element.push_back(atoi(token_results[8].c_str())); - tetra_element.push_back(atoi(token_results[10].c_str())); - tetra_element.push_back(atoi(token_results[11].c_str())); - tetra_element.push_back(atoi(token_results[12].c_str())); - tetra_element.push_back(atoi(token_results[13].c_str())); - - all_elements.push_back(tetra_element); - } - - } - while (inputfile.good()); - inputfile.close(); - - Base::Console().Log(" %f: File read, start building mesh\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - - //Now fill the SMESH datastructure - std::vector::const_iterator anodeiterator; - SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); - meshds->ClearMesh(); - unsigned int j=0; - for(anodeiterator=vertices.begin(); anodeiterator!=vertices.end(); anodeiterator++) - { - meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,nodal_id[j]); - j++; - } - - for(unsigned int i=0;iAddVolumeWithID - //( - // meshds->FindNode(all_elements[i][0]), - // meshds->FindNode(all_elements[i][2]), - // meshds->FindNode(all_elements[i][1]), - // meshds->FindNode(all_elements[i][3]), - // meshds->FindNode(all_elements[i][6]), - // meshds->FindNode(all_elements[i][5]), - // meshds->FindNode(all_elements[i][4]), - // meshds->FindNode(all_elements[i][9]), - // meshds->FindNode(all_elements[i][7]), - // meshds->FindNode(all_elements[i][8]), - // element_id[i] - //); - meshds->AddVolumeWithID - ( - meshds->FindNode(all_elements[i][1]), - meshds->FindNode(all_elements[i][0]), - meshds->FindNode(all_elements[i][2]), - meshds->FindNode(all_elements[i][3]), - meshds->FindNode(all_elements[i][4]), - meshds->FindNode(all_elements[i][6]), - meshds->FindNode(all_elements[i][5]), - meshds->FindNode(all_elements[i][8]), - meshds->FindNode(all_elements[i][7]), - meshds->FindNode(all_elements[i][9]), - element_id[i] - ); - } - Base::Console().Log(" %f: Done \n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - -} - - -void FemMesh::read(const char *FileName) -{ - Base::FileInfo File(FileName); - _Mtrx = Base::Matrix4D(); - - // checking on the file - if (!File.isReadable()) - throw Base::Exception("File to load not existing or not readable"); - - if (File.hasExtension("unv") ) { - // read UNV file - myMesh->UNVToMesh(File.filePath().c_str()); - } - else if (File.hasExtension("med") ) { - myMesh->MEDToMesh(File.filePath().c_str(),File.fileNamePure().c_str()); - } - else if (File.hasExtension("stl") ) { - // read brep-file - myMesh->STLToMesh(File.filePath().c_str()); - } - else if (File.hasExtension("dat") ) { - // read brep-file - myMesh->DATToMesh(File.filePath().c_str()); - } - else if (File.hasExtension("bdf") ) { - // read Nastran-file - readNastran(File.filePath()); - } - else{ - throw Base::Exception("Unknown extension"); - } -} - -void FemMesh::writeABAQUS(const std::string &Filename) const -{ - static std::map > elemOrderMap; - static std::map edgeTypeMap; - static std::map faceTypeMap; - static std::map volTypeMap; - if (elemOrderMap.empty()) { - // dimension 1 - // - std::vector b31 = boost::assign::list_of(0)(1); - std::vector b32 = boost::assign::list_of(0)(2)(1); - - elemOrderMap.insert(std::make_pair("B31", b31)); - edgeTypeMap.insert(std::make_pair(elemOrderMap["B31"].size(), "B31")); - elemOrderMap.insert(std::make_pair("B32", b32)); - edgeTypeMap.insert(std::make_pair(elemOrderMap["B32"].size(), "B32")); - - // dimension 2 - // - std::vector s3 = boost::assign::list_of(0)(1)(2); - std::vector s6 = boost::assign::list_of(0)(1)(2)(3)(4)(5); - // FIXME: get the right order - std::vector s4r; - std::vector s8r; - - elemOrderMap.insert(std::make_pair("S3", s3)); - faceTypeMap.insert(std::make_pair(elemOrderMap["S3"].size(), "S3")); - elemOrderMap.insert(std::make_pair("S6", s6)); - faceTypeMap.insert(std::make_pair(elemOrderMap["S6"].size(), "S6")); -#if 0 - elemOrderMap.insert(std::make_pair("S4R", s4r)); - faceTypeMap.insert(std::make_pair(elemOrderMap["S4R"].size(), "S4R")); - elemOrderMap.insert(std::make_pair("S8R", s8r)); - faceTypeMap.insert(std::make_pair(elemOrderMap["S8R"].size(), "S8R")); -#endif - - // dimension 3 - // - //std::vector c3d4 = boost::assign::list_of(0)(3)(1)(2); - //std::vector c3d10 = boost::assign::list_of(0)(2)(1)(3)(6)(5)(4)(7)(9)(8); - std::vector c3d4 = boost::assign::list_of(1)(0)(2)(3); - std::vector c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9); - // FIXME: get the right order - std::vector c3d6; - std::vector c3d8; - std::vector c3d15; - std::vector c3d20; - - elemOrderMap.insert(std::make_pair("C3D4", c3d4)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D4"].size(), "C3D4")); - elemOrderMap.insert(std::make_pair("C3D10", c3d10)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D10"].size(), "C3D10")); -#if 0 - elemOrderMap.insert(std::make_pair("C3D6", c3d6)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D6"].size(), "C3D6")); - elemOrderMap.insert(std::make_pair("C3D8", c3d8)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D8"].size(), "C3D8")); - elemOrderMap.insert(std::make_pair("C3D15", c3d15)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D15"].size(), "C3D15")); - elemOrderMap.insert(std::make_pair("C3D20", c3d20)); - volTypeMap.insert(std::make_pair(elemOrderMap["C3D20"].size(), "C3D20")); -#endif - } - - std::ofstream anABAQUS_Output; - anABAQUS_Output.open(Filename.c_str()); - - // add nodes - // - anABAQUS_Output << "*Node, NSET=Nall" << std::endl; - typedef std::map VertexMap; - VertexMap vertexMap; - - //Extract Nodes and Elements of the current SMESH datastructure - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - - Base::Vector3d current_node; - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - current_node.Set(aNode->X(),aNode->Y(),aNode->Z()); - current_node = _Mtrx * current_node; - vertexMap[aNode->GetID()] = current_node; - } - - // This way we get sorted output. - // See http://forum.freecadweb.org/viewtopic.php?f=18&t=12646&start=40#p103004 - for (VertexMap::iterator it = vertexMap.begin(); it != vertexMap.end(); ++it) { - anABAQUS_Output << it->first << ", " - << it->second.x << ", " - << it->second.y << ", " - << it->second.z << std::endl; - } - - typedef std::map > NodesMap; - typedef std::map ElementsMap; - ElementsMap elementsMap; - - // add volumes - // - SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator(); - while (aVolIter->more()) { - const SMDS_MeshVolume* aVol = aVolIter->next(); - std::pair > apair; - apair.first = aVol->GetID(); - - int numNodes = aVol->NbNodes(); - std::map::iterator it = volTypeMap.find(numNodes); - if (it != volTypeMap.end()) { - const std::vector& order = elemOrderMap[it->second]; - for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) - apair.second.push_back(aVol->GetNode(*jt)->GetID()); - elementsMap[it->second].insert(apair); - } - } - - for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { - anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; - for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { - anABAQUS_Output << jt->first << ", "; - for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { - anABAQUS_Output << *kt << ", "; - } - anABAQUS_Output << std::endl; - } - } - - if (!elementsMap.empty()) { - anABAQUS_Output.close(); - return; // done - } - - // add faces - // - elementsMap.clear(); - SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); - while (aFaceIter->more()) { - const SMDS_MeshFace* aFace = aFaceIter->next(); - std::pair > apair; - apair.first = aFace->GetID(); - - int numNodes = aFace->NbNodes(); - std::map::iterator it = faceTypeMap.find(numNodes); - if (it != faceTypeMap.end()) { - const std::vector& order = elemOrderMap[it->second]; - for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) - apair.second.push_back(aFace->GetNode(*jt)->GetID()); - elementsMap[it->second].insert(apair); - } - } - - for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { - anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; - for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { - anABAQUS_Output << jt->first << ", "; - for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { - anABAQUS_Output << *kt << ", "; - } - anABAQUS_Output << std::endl; - } - } - - if (!elementsMap.empty()) { - anABAQUS_Output.close(); - return; // done - } - - // add edges - // - elementsMap.clear(); - SMDS_EdgeIteratorPtr aEdgeIter = myMesh->GetMeshDS()->edgesIterator(); - while (aEdgeIter->more()) { - const SMDS_MeshEdge* aEdge = aEdgeIter->next(); - std::pair > apair; - apair.first = aEdge->GetID(); - - int numNodes = aEdge->NbNodes(); - std::map::iterator it = edgeTypeMap.find(numNodes); - if (it != edgeTypeMap.end()) { - const std::vector& order = elemOrderMap[it->second]; - for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) - apair.second.push_back(aEdge->GetNode(*jt)->GetID()); - elementsMap[it->second].insert(apair); - } - } - - for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { - anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; - for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { - anABAQUS_Output << jt->first << ", "; - for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { - anABAQUS_Output << *kt << ", "; - } - anABAQUS_Output << std::endl; - } - } - elementsMap.clear(); - - anABAQUS_Output.close(); -} - -void FemMesh::write(const char *FileName) const -{ - Base::FileInfo File(FileName); - - if (File.hasExtension("unv") ) { - // read UNV file - myMesh->ExportUNV(File.filePath().c_str()); - } - else if (File.hasExtension("med") ) { - myMesh->ExportMED(File.filePath().c_str()); - } - else if (File.hasExtension("stl") ) { - // read brep-file - myMesh->ExportSTL(File.filePath().c_str(),false); - } - else if (File.hasExtension("dat") ) { - // read brep-file - myMesh->ExportDAT(File.filePath().c_str()); - } - else if (File.hasExtension("inp") ) { - // write ABAQUS Output - writeABAQUS(File.filePath()); - } - else{ - throw Base::Exception("Unknown extension"); - } -} - -// ==== Base class implementer ============================================================== - -unsigned int FemMesh::getMemSize (void) const -{ - return 0; -} - -void FemMesh::Save (Base::Writer &writer) const -{ - if (!writer.isForceXML()) { - //See SaveDocFile(), RestoreDocFile() - writer.Stream() << writer.ind() << "" << std::endl; - } - else { - writer.Stream() << writer.ind() << "" << std::endl; - } -} - -void FemMesh::Restore(Base::XMLReader &reader) -{ - reader.readElement("FemMesh"); - std::string file (reader.getAttribute("file") ); - - if (!file.empty()) { - // initate a file read - reader.addFile(file.c_str(),this); - } - if( reader.hasAttribute("a11")){ - _Mtrx[0][0] = (float)reader.getAttributeAsFloat("a11"); - _Mtrx[0][1] = (float)reader.getAttributeAsFloat("a12"); - _Mtrx[0][2] = (float)reader.getAttributeAsFloat("a13"); - _Mtrx[0][3] = (float)reader.getAttributeAsFloat("a14"); - - _Mtrx[1][0] = (float)reader.getAttributeAsFloat("a21"); - _Mtrx[1][1] = (float)reader.getAttributeAsFloat("a22"); - _Mtrx[1][2] = (float)reader.getAttributeAsFloat("a23"); - _Mtrx[1][3] = (float)reader.getAttributeAsFloat("a24"); - - _Mtrx[2][0] = (float)reader.getAttributeAsFloat("a31"); - _Mtrx[2][1] = (float)reader.getAttributeAsFloat("a32"); - _Mtrx[2][2] = (float)reader.getAttributeAsFloat("a33"); - _Mtrx[2][3] = (float)reader.getAttributeAsFloat("a34"); - - _Mtrx[3][0] = (float)reader.getAttributeAsFloat("a41"); - _Mtrx[3][1] = (float)reader.getAttributeAsFloat("a42"); - _Mtrx[3][2] = (float)reader.getAttributeAsFloat("a43"); - _Mtrx[3][3] = (float)reader.getAttributeAsFloat("a44"); - } -} - -void FemMesh::SaveDocFile (Base::Writer &writer) const -{ - // create a temporary file and copy the content to the zip stream - Base::FileInfo fi(App::Application::getTempFileName().c_str()); - - myMesh->ExportUNV(fi.filePath().c_str()); - - Base::ifstream file(fi, std::ios::in | std::ios::binary); - if (file){ - unsigned long ulSize = 0; - std::streambuf* buf = file.rdbuf(); - if (buf) { - unsigned long ulCurr; - ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in); - ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in); - buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in); - } - - // read in the ASCII file and write back to the stream - std::strstreambuf sbuf(ulSize); - file >> &sbuf; - writer.Stream() << &sbuf; - } - - file.close(); - // remove temp file - fi.deleteFile(); -} - -void FemMesh::RestoreDocFile(Base::Reader &reader) -{ - // create a temporary file and copy the content from the zip stream - Base::FileInfo fi(App::Application::getTempFileName().c_str()); - - // read in the ASCII file and write back to the file stream - Base::ofstream file(fi, std::ios::out | std::ios::binary); - if (reader) - reader >> file.rdbuf(); - file.close(); - - // read the shape from the temp file - myMesh->UNVToMesh(fi.filePath().c_str()); - - // delete the temp file - fi.deleteFile(); -} - -void FemMesh::transformGeometry(const Base::Matrix4D& rclTrf) -{ - //We perform a translation and rotation of the current active Mesh object - Base::Matrix4D clMatrix(rclTrf); - SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); - Base::Vector3d current_node; - for (;aNodeIter->more();) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - current_node.Set(aNode->X(),aNode->Y(),aNode->Z()); - current_node = clMatrix * current_node; - myMesh->GetMeshDS()->MoveNode(aNode,current_node.x,current_node.y,current_node.z); - } -} - -void FemMesh::setTransform(const Base::Matrix4D& rclTrf) -{ - // Placement handling, no geometric transformation - _Mtrx = rclTrf; -} - -Base::Matrix4D FemMesh::getTransform(void) const -{ - return _Mtrx; -} - -Base::BoundBox3d FemMesh::getBoundBox(void) const -{ - Base::BoundBox3d box; - - SMESHDS_Mesh* data = const_cast(getSMesh())->GetMeshDS(); - - SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator(); - for (;aNodeIter->more();) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - // Apply the matrix to hold the BoundBox in absolute space. - vec = _Mtrx * vec; - box.Add(vec); - } - - return box; -} - -std::vector FemMesh::getElementTypes(void) const -{ - std::vector temp; - temp.push_back("Vertex"); - temp.push_back("Edge"); - temp.push_back("Face"); - temp.push_back("Volume"); - - return temp; -} - -unsigned long FemMesh::countSubElements(const char* Type) const -{ - return 0; -} - -Data::Segment* FemMesh::getSubElement(const char* Type, unsigned long n) const -{ - // FIXME implement subelement interface - //std::stringstream str; - //str << Type << n; - //std::string temp = str.str(); - //return new ShapeSegment(getSubShape(temp.c_str())); - return 0; -} - -struct Fem::FemMesh::FemMeshInfo FemMesh::getInfo(void) const{ - - struct FemMeshInfo rtrn; - - SMESHDS_Mesh* data = const_cast(getSMesh())->GetMeshDS(); - const SMDS_MeshInfo& info = data->GetMeshInfo(); - rtrn.numFaces = data->NbFaces(); - rtrn.numNode = info.NbNodes(); - rtrn.numTria = info.NbTriangles(); - rtrn.numQuad = info.NbQuadrangles(); - rtrn.numPoly = info.NbPolygons(); - rtrn.numVolu = info.NbVolumes(); - rtrn.numTetr = info.NbTetras(); - rtrn.numHexa = info.NbHexas(); - rtrn.numPyrd = info.NbPyramids(); - rtrn.numPris = info.NbPrisms(); - rtrn.numHedr = info.NbPolyhedrons(); - - return rtrn; - -} -// for(unsigned int i=0;iAddVolumeWithID( -// meshds->FindNode(all_elements[i][0]), -// meshds->FindNode(all_elements[i][2]), -// meshds->FindNode(all_elements[i][1]), -// meshds->FindNode(all_elements[i][3]), -// meshds->FindNode(all_elements[i][6]), -// meshds->FindNode(all_elements[i][5]), -// meshds->FindNode(all_elements[i][4]), -// meshds->FindNode(all_elements[i][9]), -// meshds->FindNode(all_elements[i][7]), -// meshds->FindNode(all_elements[i][8]), -// element_id[i] -// ); -// } - -Base::Quantity FemMesh::getVolume(void)const -{ - SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator(); - - //Calculate Mesh Volume - //For an accurate Volume Calculation of a quadratic Tetrahedron - //we have to calculate the Volume of 8 Sub-Tetrahedrons - Base::Vector3d a,b,c,a_b_product; - double volume = 0.0; - - for (;aVolIter->more();) - { - const SMDS_MeshVolume* aVol = aVolIter->next(); - - if ( aVol->NbNodes() != 10 ) continue; - - Base::Vector3d v1(aVol->GetNode(1)->X(),aVol->GetNode(1)->Y(),aVol->GetNode(1)->Z()); - Base::Vector3d v0(aVol->GetNode(0)->X(),aVol->GetNode(0)->Y(),aVol->GetNode(0)->Z()); - Base::Vector3d v2(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z()); - Base::Vector3d v3(aVol->GetNode(3)->X(),aVol->GetNode(3)->Y(),aVol->GetNode(3)->Z()); - Base::Vector3d v4(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z()); - Base::Vector3d v6(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z()); - Base::Vector3d v5(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z()); - Base::Vector3d v8(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z()); - Base::Vector3d v7(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z()); - Base::Vector3d v9(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z()); - - - //1,5,8,7 - a = v4 -v0 ; - b = v7 -v0 ; - c = v6 -v0 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //5,9,8,7 - a = v8 -v4 ; - b = v7 -v4 ; - c = v6 -v4 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //5,2,9,7 - a = v1 -v4 ; - b = v8 -v4 ; - c = v6 -v4 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //2,6,9,7 - a = v5 -v1 ; - b = v8 -v1 ; - c = v6 -v1 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //9,6,10,7 - a = v5 -v8 ; - b = v9 -v8 ; - c = v6 -v8 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //6,3,10,7 - a = v2 -v5 ; - b = v9 -v5 ; - c = v6 -v5 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //8,9,10,7 - a = v8 -v7 ; - b = v9 -v7 ; - c = v6 -v7 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - //8,9,10,4 - a = v8 -v7 ; - b = v9 -v7 ; - c = v3 -v7 ; - a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; - volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); - - } - - return Base::Quantity(volume,Unit::Volume); - - -} +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "FemMesh.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +# include + +//to simplify parsing input files we use the boost lib +#include + + +using namespace Fem; +using namespace Base; +using namespace boost; + +static int StatCount = 0; + +TYPESYSTEM_SOURCE(Fem::FemMesh , Base::Persistence); + +FemMesh::FemMesh() +{ + //Base::Console().Log("FemMesh::FemMesh():%p (id=%i)\n",this,StatCount); + myGen = new SMESH_Gen(); + // create a mesh allways with new StudyId to avoid overlapping destruction + myMesh = myGen->CreateMesh(StatCount++,false); + +} + +FemMesh::FemMesh(const FemMesh& mesh) +{ + //Base::Console().Log("FemMesh::FemMesh(mesh):%p (id=%i)\n",this,StatCount); + myGen = new SMESH_Gen(); + myMesh = myGen->CreateMesh(StatCount++,false); + copyMeshData(mesh); +} + +FemMesh::~FemMesh() +{ + //Base::Console().Log("FemMesh::~FemMesh():%p\n",this); + + TopoDS_Shape aNull; + myMesh->ShapeToMesh(aNull); + myMesh->Clear(); + //myMesh->ClearLog(); + delete myMesh; +#if defined(__GNUC__) + delete myGen; // crashes with MSVC +#endif +} + +FemMesh &FemMesh::operator=(const FemMesh& mesh) +{ + if (this != &mesh) { + copyMeshData(mesh); + } + return *this; +} + +void FemMesh::copyMeshData(const FemMesh& mesh) +{ + //const SMDS_MeshInfo& info = mesh.myMesh->GetMeshDS()->GetMeshInfo(); + //int numPoly = info.NbPolygons(); + //int numVolu = info.NbVolumes(); + //int numTetr = info.NbTetras(); + //int numHexa = info.NbHexas(); + //int numPyrd = info.NbPyramids(); + //int numPris = info.NbPrisms(); + //int numHedr = info.NbPolyhedrons(); + + _Mtrx = mesh._Mtrx; + + SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); + meshds->ClearMesh(); + + SMDS_NodeIteratorPtr aNodeIter = mesh.myMesh->GetMeshDS()->nodesIterator(); + for (;aNodeIter->more();) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + meshds->AddNodeWithID(aNode->X(),aNode->Y(),aNode->Z(), aNode->GetID()); + } + + SMDS_EdgeIteratorPtr aEdgeIter = mesh.myMesh->GetMeshDS()->edgesIterator(); + for (;aEdgeIter->more();) { + const SMDS_MeshEdge* aEdge = aEdgeIter->next(); + meshds->AddEdgeWithID(aEdge->GetNode(0), aEdge->GetNode(1), aEdge->GetID()); + } + + SMDS_FaceIteratorPtr aFaceIter = mesh.myMesh->GetMeshDS()->facesIterator(); + for (;aFaceIter->more();) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + switch (aFace->NbNodes()) { + case 3: + meshds->AddFaceWithID(aFace->GetNode(0), + aFace->GetNode(1), + aFace->GetNode(2), + aFace->GetID()); + break; + case 4: + meshds->AddFaceWithID(aFace->GetNode(0), + aFace->GetNode(1), + aFace->GetNode(2), + aFace->GetNode(3), + aFace->GetID()); + break; + case 6: + meshds->AddFaceWithID(aFace->GetNode(0), + aFace->GetNode(1), + aFace->GetNode(2), + aFace->GetNode(3), + aFace->GetNode(4), + aFace->GetNode(5), + aFace->GetID()); + break; + case 8: + meshds->AddFaceWithID(aFace->GetNode(0), + aFace->GetNode(1), + aFace->GetNode(2), + aFace->GetNode(3), + aFace->GetNode(4), + aFace->GetNode(5), + aFace->GetNode(6), + aFace->GetNode(7), + aFace->GetID()); + break; + default: + { + std::vector aNodes; + for (int i=0; aFace->NbNodes(); i++) + aNodes.push_back(aFace->GetNode(0)); + meshds->AddPolygonalFaceWithID(aNodes, aFace->GetID()); + } + break; + } + } + + SMDS_VolumeIteratorPtr aVolIter = mesh.myMesh->GetMeshDS()->volumesIterator(); + for (;aVolIter->more();) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + switch (aVol->NbNodes()) { + case 4: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetID()); + break; + case 5: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetID()); + break; + case 6: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetID()); + break; + case 8: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetNode(6), + aVol->GetNode(7), + aVol->GetID()); + break; + case 10: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetNode(6), + aVol->GetNode(7), + aVol->GetNode(8), + aVol->GetNode(9), + aVol->GetID()); + break; + case 13: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetNode(6), + aVol->GetNode(7), + aVol->GetNode(8), + aVol->GetNode(9), + aVol->GetNode(10), + aVol->GetNode(11), + aVol->GetNode(12), + aVol->GetID()); + break; + case 15: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetNode(6), + aVol->GetNode(7), + aVol->GetNode(8), + aVol->GetNode(9), + aVol->GetNode(10), + aVol->GetNode(11), + aVol->GetNode(12), + aVol->GetNode(13), + aVol->GetNode(14), + aVol->GetID()); + break; + case 20: + meshds->AddVolumeWithID(aVol->GetNode(0), + aVol->GetNode(1), + aVol->GetNode(2), + aVol->GetNode(3), + aVol->GetNode(4), + aVol->GetNode(5), + aVol->GetNode(6), + aVol->GetNode(7), + aVol->GetNode(8), + aVol->GetNode(9), + aVol->GetNode(10), + aVol->GetNode(11), + aVol->GetNode(12), + aVol->GetNode(13), + aVol->GetNode(14), + aVol->GetNode(15), + aVol->GetNode(16), + aVol->GetNode(17), + aVol->GetNode(18), + aVol->GetNode(19), + aVol->GetID()); + break; + default: + { + if (aVol->IsPoly()) { + const SMDS_PolyhedralVolumeOfNodes* aPolyVol = dynamic_cast(aVol); + if (!aPolyVol) break; + std::vector aNodes; + for (int i=0; iNbNodes(); i++) + aNodes.push_back(aPolyVol->GetNode(i)); + meshds->AddPolyhedralVolumeWithID(aNodes, + aPolyVol->GetQuanities(), aPolyVol->GetID()); + } + } + break; + } + } +} + +const SMESH_Mesh* FemMesh::getSMesh() const +{ + return myMesh; +} + +SMESH_Mesh* FemMesh::getSMesh() +{ + return myMesh; +} + + +SMESH_Gen * FemMesh::getGenerator() +{ + return myGen; +} + +void FemMesh::addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp) +{ + myMesh->AddHypothesis(aSubShape, hyp->GetID()); + SMESH_HypothesisPtr ptr(hyp); + hypoth.push_back(ptr); +} + +void FemMesh::setStanardHypotheses() +{ + if (!hypoth.empty()) + return; + int hyp=0; + SMESH_HypothesisPtr len(new StdMeshers_MaxLength(hyp++, 1, myGen)); + static_cast(len.get())->SetLength(1.0); + hypoth.push_back(len); + + SMESH_HypothesisPtr loc(new StdMeshers_LocalLength(hyp++, 1, myGen)); + static_cast(loc.get())->SetLength(1.0); + hypoth.push_back(loc); + + SMESH_HypothesisPtr area(new StdMeshers_MaxElementArea(hyp++, 1, myGen)); + static_cast(area.get())->SetMaxArea(1.0); + hypoth.push_back(area); + + SMESH_HypothesisPtr segm(new StdMeshers_NumberOfSegments(hyp++, 1, myGen)); + static_cast(segm.get())->SetNumberOfSegments(1); + hypoth.push_back(segm); + + SMESH_HypothesisPtr defl(new StdMeshers_Deflection1D(hyp++, 1, myGen)); + static_cast(defl.get())->SetDeflection(0.01); + hypoth.push_back(defl); + + SMESH_HypothesisPtr reg(new StdMeshers_Regular_1D(hyp++, 1, myGen)); + hypoth.push_back(reg); + + //SMESH_HypothesisPtr sel(new StdMeshers_StartEndLength(hyp++, 1, myGen)); + //static_cast(sel.get())->SetLength(1.0, true); + //hypoth.push_back(sel); + + SMESH_HypothesisPtr qdp(new StdMeshers_QuadranglePreference(hyp++,1,myGen)); + hypoth.push_back(qdp); + + SMESH_HypothesisPtr q2d(new StdMeshers_Quadrangle_2D(hyp++,1,myGen)); + hypoth.push_back(q2d); + + // Apply hypothesis + for (int i=0; iAddHypothesis(myMesh->GetShapeToMesh(), i); +} + +void FemMesh::compute() +{ + myGen->Compute(*myMesh, myMesh->GetShapeToMesh()); +} + +std::set FemMesh::getSurfaceNodes(long ElemId, short FaceId, float Angle) const +{ + std::set result; + //const SMESHDS_Mesh* data = myMesh->GetMeshDS(); + + //const SMDS_MeshElement * element = data->FindElement(ElemId); + //int fNbr = element->NbFaces(); + //element-> + + return result; +} + +/*! That function returns map containing volume ID and face ID. + */ +std::list > FemMesh::getVolumesByFace(const TopoDS_Face &face) const +{ + std::list > result; + std::set nodes_on_face = getNodesByFace(face); + + SMDS_VolumeIteratorPtr vol_iter = myMesh->GetMeshDS()->volumesIterator(); + while (vol_iter->more()) { + const SMDS_MeshVolume* vol = vol_iter->next(); + SMDS_ElemIteratorPtr face_iter = vol->facesIterator(); + + while (face_iter->more()) { + const SMDS_MeshFace* face = static_cast(face_iter->next()); + int numNodes = face->NbNodes(); + + std::set face_nodes; + for (int i=0; iGetNode(i)->GetID()); + } + + std::vector element_face_nodes; + std::set_intersection(nodes_on_face.begin(), nodes_on_face.end(), face_nodes.begin(), face_nodes.end(), + std::back_insert_iterator >(element_face_nodes)); + + // For curved faces it is possible that a volume contributes more than one face + if (element_face_nodes.size() == static_cast(numNodes)) { + result.push_back(std::make_pair(vol->GetID(), face->GetID())); + } + } + } + + result.sort(); + return result; +} + +/*! That function returns map containing volume ID and face number + * as per CalculiX definition for tetrahedral elements. See CalculiX + * documentation for the details. + */ +std::map FemMesh::getccxVolumesByFace(const TopoDS_Face &face) const +{ + std::map result; + std::set nodes_on_face = getNodesByFace(face); + + static std::map > elem_order; + if (elem_order.empty()) { + std::vector c3d4 = boost::assign::list_of(1)(0)(2)(3); + std::vector c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9); + + elem_order.insert(std::make_pair(c3d4.size(), c3d4)); + elem_order.insert(std::make_pair(c3d10.size(), c3d10)); + } + + SMDS_VolumeIteratorPtr vol_iter = myMesh->GetMeshDS()->volumesIterator(); + std::set element_nodes; + int num_of_nodes; + while (vol_iter->more()) { + const SMDS_MeshVolume* vol = vol_iter->next(); + num_of_nodes = vol->NbNodes(); + std::pair > apair; + apair.first = vol->GetID(); + + std::map >::iterator it = elem_order.find(num_of_nodes); + if (it != elem_order.end()) { + const std::vector& order = it->second; + for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) { + int vid = vol->GetNode(*jt)->GetID(); + apair.second.push_back(vid); + } + } + + // Get volume nodes on face + std::vector element_face_nodes; + std::set element_nodes; + element_nodes.insert(apair.second.begin(), apair.second.end()); + std::set_intersection(nodes_on_face.begin(), nodes_on_face.end(), element_nodes.begin(), element_nodes.end(), + std::back_insert_iterator >(element_face_nodes)); + + if ((element_face_nodes.size() == 3 && num_of_nodes == 4) || + (element_face_nodes.size() == 6 && num_of_nodes == 10)) { + int missing_node = 0; + for (int i=0; i<4; i++) { + // search for the ID of the volume which is not part of 'element_face_nodes' + if (std::find(element_face_nodes.begin(), element_face_nodes.end(), apair.second[i]) == element_face_nodes.end()) { + missing_node = i + 1; + break; + } + } + /* for tetrahedral elements as per CalculiX definition: + Face 1: 1-2-3, missing point 4 means it's face P1 + Face 2: 1-4-2, missing point 3 means it's face P2 + Face 3: 2-4-3, missing point 1 means it's face P3 + Face 4: 3-4-1, missing point 2 means it's face P4 */ + int face_ccx = 0; + switch (missing_node) { + case 1: + face_ccx = 3; + break; + case 2: + face_ccx = 4; + break; + case 3: + face_ccx = 2; + break; + case 4: + face_ccx = 1; + break; + default: + assert(false); // should never happen + break; + } + result[apair.first] = face_ccx; + } + } + + return result; +} + +std::set FemMesh::getNodesBySolid(const TopoDS_Solid &solid) const +{ + std::set result; + + Bnd_Box box; + BRepBndLib::Add(solid, box); + // limit where the mesh node belongs to the solid: + double limit = box.SquareExtent()/10000.0; + //double limit = BRep_Tool::Tolerance(solid); // does not compile --> no matching function for call to 'BRep_Tool::Tolerance(const TopoDS_Solid&)' + box.Enlarge(limit); + + // get the current transform of the FemMesh + const Base::Matrix4D Mtrx(getTransform()); + + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = Mtrx * vec; + + if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { + // create a vertex + BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); + TopoDS_Shape s = aBuilder.Vertex(); + // measure distance + BRepExtrema_DistShapeShape measure(solid,s); + measure.Perform(); + if (!measure.IsDone() || measure.NbSolution() < 1) + continue; + + if (measure.Value() < limit) + result.insert(aNode->GetID()); + } + } + + return result; +} + +std::set FemMesh::getNodesByFace(const TopoDS_Face &face) const +{ + std::set result; + + Bnd_Box box; + BRepBndLib::Add(face, box); + // limit where the mesh node belongs to the face: + double limit = BRep_Tool::Tolerance(face); + box.Enlarge(limit); + + // get the current transform of the FemMesh + const Base::Matrix4D Mtrx(getTransform()); + + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = Mtrx * vec; + + if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { + // create a vertex + BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); + TopoDS_Shape s = aBuilder.Vertex(); + // measure distance + BRepExtrema_DistShapeShape measure(face,s); + measure.Perform(); + if (!measure.IsDone() || measure.NbSolution() < 1) + continue; + + if (measure.Value() < limit) + result.insert(aNode->GetID()); + } + } + + return result; +} + +std::set FemMesh::getNodesByEdge(const TopoDS_Edge &edge) const +{ + std::set result; + + Bnd_Box box; + BRepBndLib::Add(edge, box); + // limit where the mesh node belongs to the edge: + double limit = BRep_Tool::Tolerance(edge); + box.Enlarge(limit); + + // get the current transform of the FemMesh + const Base::Matrix4D Mtrx(getTransform()); + + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = Mtrx * vec; + + if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { + // create a vertex + BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); + TopoDS_Shape s = aBuilder.Vertex(); + // measure distance + BRepExtrema_DistShapeShape measure(edge,s); + measure.Perform(); + if (!measure.IsDone() || measure.NbSolution() < 1) + continue; + + if (measure.Value() < limit) + result.insert(aNode->GetID()); + } + } + + return result; +} + +std::set FemMesh::getNodesByVertex(const TopoDS_Vertex &vertex) const +{ + std::set result; + + double limit = BRep_Tool::Tolerance(vertex); + limit *= limit; // use square to improve speed + gp_Pnt pnt = BRep_Tool::Pnt(vertex); + Base::Vector3d node(pnt.X(), pnt.Y(), pnt.Z()); + + // get the current transform of the FemMesh + const Base::Matrix4D Mtrx(getTransform()); + + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + vec = Mtrx * vec; + + if (Base::DistanceP2(node, vec) <= limit) { + result.insert(aNode->GetID()); + } + } + + return result; +} + +std::list FemMesh::getElementNodes(int id) const +{ + std::list result; + const SMDS_MeshElement* elem = myMesh->GetMeshDS()->FindElement(id); + if (elem) { + for (int i = 0; i < elem->NbNodes(); i++) + result.push_back(elem->GetNode(i)->GetID()); + } + return result; +} + +void FemMesh::readNastran(const std::string &Filename) +{ + Base::TimeInfo Start; + Base::Console().Log("Start: FemMesh::readNastran() =================================\n"); + + _Mtrx = Base::Matrix4D(); + + std::ifstream inputfile; + inputfile.open(Filename.c_str()); + inputfile.seekg(std::ifstream::beg); + std::string line1,line2,temp; + std::vector token_results; + token_results.clear(); + Base::Vector3d current_node; + std::vector vertices; + vertices.clear(); + std::vector nodal_id; + nodal_id.clear(); + std::vector tetra_element; + std::vector > all_elements; + std::vector element_id; + element_id.clear(); + bool nastran_free_format = false; + do + { + std::getline(inputfile,line1); + if (line1.size() == 0) continue; + if (!nastran_free_format && line1.find(",")!= std::string::npos) + nastran_free_format = true; + if (!nastran_free_format && line1.find("GRID*")!= std::string::npos ) //We found a Grid line + { + //Now lets extract the GRID Points = Nodes + //As each GRID Line consists of two subsequent lines we have to + //take care of that as well + std::getline(inputfile,line2); + //Get the Nodal ID + nodal_id.push_back(atoi(line1.substr(8,24).c_str())); + //Extract X Value + current_node.x = atof(line1.substr(40,56).c_str()); + //Extract Y Value + current_node.y = atof(line1.substr(56,72).c_str()); + //Extract Z Value + current_node.z = atof(line2.substr(8,24).c_str()); + + vertices.push_back(current_node); + } + else if (!nastran_free_format && line1.find("CTETRA")!= std::string::npos) + { + tetra_element.clear(); + //Lets extract the elements + //As each Element Line consists of two subsequent lines as well + //we have to take care of that + //At a first step we only extract Quadratic Tetrahedral Elements + std::getline(inputfile,line2); + unsigned int id = atoi(line1.substr(8,16).c_str()); + int offset = 0; + + if(id < 1000000) + offset = 0; + else if (id < 10000000) + offset = 1; + else if (id < 100000000) + offset = 2; + + + element_id.push_back(id); + tetra_element.push_back(atoi(line1.substr(24,32).c_str())); + tetra_element.push_back(atoi(line1.substr(32,40).c_str())); + tetra_element.push_back(atoi(line1.substr(40,48).c_str())); + tetra_element.push_back(atoi(line1.substr(48,56).c_str())); + tetra_element.push_back(atoi(line1.substr(56,64).c_str())); + tetra_element.push_back(atoi(line1.substr(64,72).c_str())); + tetra_element.push_back(atoi(line2.substr(8+offset,16+offset).c_str())); + tetra_element.push_back(atoi(line2.substr(16+offset,24+offset).c_str())); + tetra_element.push_back(atoi(line2.substr(24+offset,32+offset).c_str())); + tetra_element.push_back(atoi(line2.substr(32+offset,40+offset).c_str())); + + all_elements.push_back(tetra_element); + } + else if (nastran_free_format && line1.find("GRID")!= std::string::npos ) //We found a Grid line + { + char_separator sep(","); + tokenizer > tokens(line1, sep); + token_results.assign(tokens.begin(),tokens.end()); + if (token_results.size() < 3) + continue;//Line does not include Nodal coordinates + nodal_id.push_back(atoi(token_results[1].c_str())); + current_node.x = atof(token_results[3].c_str()); + current_node.y = atof(token_results[4].c_str()); + current_node.z = atof(token_results[5].c_str()); + vertices.push_back(current_node); + } + else if (nastran_free_format && line1.find("CTETRA")!= std::string::npos) + { + tetra_element.clear(); + //Lets extract the elements + //As each Element Line consists of two subsequent lines as well + //we have to take care of that + //At a first step we only extract Quadratic Tetrahedral Elements + std::getline(inputfile,line2); + char_separator sep(","); + tokenizer > tokens(line1.append(line2), sep); + token_results.assign(tokens.begin(),tokens.end()); + if (token_results.size() < 11) + continue;//Line does not include enough nodal IDs + element_id.push_back(atoi(token_results[1].c_str())); + tetra_element.push_back(atoi(token_results[3].c_str())); + tetra_element.push_back(atoi(token_results[4].c_str())); + tetra_element.push_back(atoi(token_results[5].c_str())); + tetra_element.push_back(atoi(token_results[6].c_str())); + tetra_element.push_back(atoi(token_results[7].c_str())); + tetra_element.push_back(atoi(token_results[8].c_str())); + tetra_element.push_back(atoi(token_results[10].c_str())); + tetra_element.push_back(atoi(token_results[11].c_str())); + tetra_element.push_back(atoi(token_results[12].c_str())); + tetra_element.push_back(atoi(token_results[13].c_str())); + + all_elements.push_back(tetra_element); + } + + } + while (inputfile.good()); + inputfile.close(); + + Base::Console().Log(" %f: File read, start building mesh\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + //Now fill the SMESH datastructure + std::vector::const_iterator anodeiterator; + SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); + meshds->ClearMesh(); + unsigned int j=0; + for(anodeiterator=vertices.begin(); anodeiterator!=vertices.end(); anodeiterator++) + { + meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,nodal_id[j]); + j++; + } + + for(unsigned int i=0;iAddVolumeWithID + //( + // meshds->FindNode(all_elements[i][0]), + // meshds->FindNode(all_elements[i][2]), + // meshds->FindNode(all_elements[i][1]), + // meshds->FindNode(all_elements[i][3]), + // meshds->FindNode(all_elements[i][6]), + // meshds->FindNode(all_elements[i][5]), + // meshds->FindNode(all_elements[i][4]), + // meshds->FindNode(all_elements[i][9]), + // meshds->FindNode(all_elements[i][7]), + // meshds->FindNode(all_elements[i][8]), + // element_id[i] + //); + meshds->AddVolumeWithID + ( + meshds->FindNode(all_elements[i][1]), + meshds->FindNode(all_elements[i][0]), + meshds->FindNode(all_elements[i][2]), + meshds->FindNode(all_elements[i][3]), + meshds->FindNode(all_elements[i][4]), + meshds->FindNode(all_elements[i][6]), + meshds->FindNode(all_elements[i][5]), + meshds->FindNode(all_elements[i][8]), + meshds->FindNode(all_elements[i][7]), + meshds->FindNode(all_elements[i][9]), + element_id[i] + ); + } + Base::Console().Log(" %f: Done \n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + +} + + +void FemMesh::read(const char *FileName) +{ + Base::FileInfo File(FileName); + _Mtrx = Base::Matrix4D(); + + // checking on the file + if (!File.isReadable()) + throw Base::Exception("File to load not existing or not readable"); + + if (File.hasExtension("unv") ) { + // read UNV file + myMesh->UNVToMesh(File.filePath().c_str()); + } + else if (File.hasExtension("med") ) { + myMesh->MEDToMesh(File.filePath().c_str(),File.fileNamePure().c_str()); + } + else if (File.hasExtension("stl") ) { + // read brep-file + myMesh->STLToMesh(File.filePath().c_str()); + } + else if (File.hasExtension("dat") ) { + // read brep-file + myMesh->DATToMesh(File.filePath().c_str()); + } + else if (File.hasExtension("bdf") ) { + // read Nastran-file + readNastran(File.filePath()); + } + else{ + throw Base::Exception("Unknown extension"); + } +} + +void FemMesh::writeABAQUS(const std::string &Filename) const +{ + static std::map > elemOrderMap; + static std::map edgeTypeMap; + static std::map faceTypeMap; + static std::map volTypeMap; + if (elemOrderMap.empty()) { + // dimension 1 + // + std::vector b31 = boost::assign::list_of(0)(1); + std::vector b32 = boost::assign::list_of(0)(2)(1); + + elemOrderMap.insert(std::make_pair("B31", b31)); + edgeTypeMap.insert(std::make_pair(elemOrderMap["B31"].size(), "B31")); + elemOrderMap.insert(std::make_pair("B32", b32)); + edgeTypeMap.insert(std::make_pair(elemOrderMap["B32"].size(), "B32")); + + // dimension 2 + // + std::vector s3 = boost::assign::list_of(0)(1)(2); + std::vector s6 = boost::assign::list_of(0)(1)(2)(3)(4)(5); + // FIXME: get the right order + std::vector s4r; + std::vector s8r; + + elemOrderMap.insert(std::make_pair("S3", s3)); + faceTypeMap.insert(std::make_pair(elemOrderMap["S3"].size(), "S3")); + elemOrderMap.insert(std::make_pair("S6", s6)); + faceTypeMap.insert(std::make_pair(elemOrderMap["S6"].size(), "S6")); +#if 0 + elemOrderMap.insert(std::make_pair("S4R", s4r)); + faceTypeMap.insert(std::make_pair(elemOrderMap["S4R"].size(), "S4R")); + elemOrderMap.insert(std::make_pair("S8R", s8r)); + faceTypeMap.insert(std::make_pair(elemOrderMap["S8R"].size(), "S8R")); +#endif + + // dimension 3 + // + //std::vector c3d4 = boost::assign::list_of(0)(3)(1)(2); + //std::vector c3d10 = boost::assign::list_of(0)(2)(1)(3)(6)(5)(4)(7)(9)(8); + std::vector c3d4 = boost::assign::list_of(1)(0)(2)(3); + std::vector c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9); + // FIXME: get the right order + std::vector c3d6; + std::vector c3d8; + std::vector c3d15; + std::vector c3d20; + + elemOrderMap.insert(std::make_pair("C3D4", c3d4)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D4"].size(), "C3D4")); + elemOrderMap.insert(std::make_pair("C3D10", c3d10)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D10"].size(), "C3D10")); +#if 0 + elemOrderMap.insert(std::make_pair("C3D6", c3d6)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D6"].size(), "C3D6")); + elemOrderMap.insert(std::make_pair("C3D8", c3d8)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D8"].size(), "C3D8")); + elemOrderMap.insert(std::make_pair("C3D15", c3d15)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D15"].size(), "C3D15")); + elemOrderMap.insert(std::make_pair("C3D20", c3d20)); + volTypeMap.insert(std::make_pair(elemOrderMap["C3D20"].size(), "C3D20")); +#endif + } + + std::ofstream anABAQUS_Output; + anABAQUS_Output.open(Filename.c_str()); + + // add nodes + // + anABAQUS_Output << "*Node, NSET=Nall" << std::endl; + typedef std::map VertexMap; + VertexMap vertexMap; + + //Extract Nodes and Elements of the current SMESH datastructure + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + + Base::Vector3d current_node; + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + current_node.Set(aNode->X(),aNode->Y(),aNode->Z()); + current_node = _Mtrx * current_node; + vertexMap[aNode->GetID()] = current_node; + } + + // This way we get sorted output. + // See http://forum.freecadweb.org/viewtopic.php?f=18&t=12646&start=40#p103004 + for (VertexMap::iterator it = vertexMap.begin(); it != vertexMap.end(); ++it) { + anABAQUS_Output << it->first << ", " + << it->second.x << ", " + << it->second.y << ", " + << it->second.z << std::endl; + } + + typedef std::map > NodesMap; + typedef std::map ElementsMap; + ElementsMap elementsMap; + + // add volumes + // + SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator(); + while (aVolIter->more()) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + std::pair > apair; + apair.first = aVol->GetID(); + + int numNodes = aVol->NbNodes(); + std::map::iterator it = volTypeMap.find(numNodes); + if (it != volTypeMap.end()) { + const std::vector& order = elemOrderMap[it->second]; + for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) + apair.second.push_back(aVol->GetNode(*jt)->GetID()); + elementsMap[it->second].insert(apair); + } + } + + for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { + anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; + for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { + anABAQUS_Output << jt->first << ", "; + for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { + anABAQUS_Output << *kt << ", "; + } + anABAQUS_Output << std::endl; + } + } + + if (!elementsMap.empty()) { + anABAQUS_Output.close(); + return; // done + } + + // add faces + // + elementsMap.clear(); + SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); + while (aFaceIter->more()) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + std::pair > apair; + apair.first = aFace->GetID(); + + int numNodes = aFace->NbNodes(); + std::map::iterator it = faceTypeMap.find(numNodes); + if (it != faceTypeMap.end()) { + const std::vector& order = elemOrderMap[it->second]; + for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) + apair.second.push_back(aFace->GetNode(*jt)->GetID()); + elementsMap[it->second].insert(apair); + } + } + + for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { + anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; + for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { + anABAQUS_Output << jt->first << ", "; + for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { + anABAQUS_Output << *kt << ", "; + } + anABAQUS_Output << std::endl; + } + } + + if (!elementsMap.empty()) { + anABAQUS_Output.close(); + return; // done + } + + // add edges + // + elementsMap.clear(); + SMDS_EdgeIteratorPtr aEdgeIter = myMesh->GetMeshDS()->edgesIterator(); + while (aEdgeIter->more()) { + const SMDS_MeshEdge* aEdge = aEdgeIter->next(); + std::pair > apair; + apair.first = aEdge->GetID(); + + int numNodes = aEdge->NbNodes(); + std::map::iterator it = edgeTypeMap.find(numNodes); + if (it != edgeTypeMap.end()) { + const std::vector& order = elemOrderMap[it->second]; + for (std::vector::const_iterator jt = order.begin(); jt != order.end(); ++jt) + apair.second.push_back(aEdge->GetNode(*jt)->GetID()); + elementsMap[it->second].insert(apair); + } + } + + for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) { + anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl; + for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { + anABAQUS_Output << jt->first << ", "; + for (std::vector::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) { + anABAQUS_Output << *kt << ", "; + } + anABAQUS_Output << std::endl; + } + } + elementsMap.clear(); + + anABAQUS_Output.close(); +} + +void FemMesh::write(const char *FileName) const +{ + Base::FileInfo File(FileName); + + if (File.hasExtension("unv") ) { + // read UNV file + myMesh->ExportUNV(File.filePath().c_str()); + } + else if (File.hasExtension("med") ) { + myMesh->ExportMED(File.filePath().c_str()); + } + else if (File.hasExtension("stl") ) { + // read brep-file + myMesh->ExportSTL(File.filePath().c_str(),false); + } + else if (File.hasExtension("dat") ) { + // read brep-file + myMesh->ExportDAT(File.filePath().c_str()); + } + else if (File.hasExtension("inp") ) { + // write ABAQUS Output + writeABAQUS(File.filePath()); + } + else{ + throw Base::Exception("Unknown extension"); + } +} + +// ==== Base class implementer ============================================================== + +unsigned int FemMesh::getMemSize (void) const +{ + return 0; +} + +void FemMesh::Save (Base::Writer &writer) const +{ + if (!writer.isForceXML()) { + //See SaveDocFile(), RestoreDocFile() + writer.Stream() << writer.ind() << "" << std::endl; + } + else { + writer.Stream() << writer.ind() << "" << std::endl; + } +} + +void FemMesh::Restore(Base::XMLReader &reader) +{ + reader.readElement("FemMesh"); + std::string file (reader.getAttribute("file") ); + + if (!file.empty()) { + // initate a file read + reader.addFile(file.c_str(),this); + } + if( reader.hasAttribute("a11")){ + _Mtrx[0][0] = (float)reader.getAttributeAsFloat("a11"); + _Mtrx[0][1] = (float)reader.getAttributeAsFloat("a12"); + _Mtrx[0][2] = (float)reader.getAttributeAsFloat("a13"); + _Mtrx[0][3] = (float)reader.getAttributeAsFloat("a14"); + + _Mtrx[1][0] = (float)reader.getAttributeAsFloat("a21"); + _Mtrx[1][1] = (float)reader.getAttributeAsFloat("a22"); + _Mtrx[1][2] = (float)reader.getAttributeAsFloat("a23"); + _Mtrx[1][3] = (float)reader.getAttributeAsFloat("a24"); + + _Mtrx[2][0] = (float)reader.getAttributeAsFloat("a31"); + _Mtrx[2][1] = (float)reader.getAttributeAsFloat("a32"); + _Mtrx[2][2] = (float)reader.getAttributeAsFloat("a33"); + _Mtrx[2][3] = (float)reader.getAttributeAsFloat("a34"); + + _Mtrx[3][0] = (float)reader.getAttributeAsFloat("a41"); + _Mtrx[3][1] = (float)reader.getAttributeAsFloat("a42"); + _Mtrx[3][2] = (float)reader.getAttributeAsFloat("a43"); + _Mtrx[3][3] = (float)reader.getAttributeAsFloat("a44"); + } +} + +void FemMesh::SaveDocFile (Base::Writer &writer) const +{ + // create a temporary file and copy the content to the zip stream + Base::FileInfo fi(App::Application::getTempFileName().c_str()); + + myMesh->ExportUNV(fi.filePath().c_str()); + + Base::ifstream file(fi, std::ios::in | std::ios::binary); + if (file){ + unsigned long ulSize = 0; + std::streambuf* buf = file.rdbuf(); + if (buf) { + unsigned long ulCurr; + ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in); + ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in); + buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in); + } + + // read in the ASCII file and write back to the stream + std::strstreambuf sbuf(ulSize); + file >> &sbuf; + writer.Stream() << &sbuf; + } + + file.close(); + // remove temp file + fi.deleteFile(); +} + +void FemMesh::RestoreDocFile(Base::Reader &reader) +{ + // create a temporary file and copy the content from the zip stream + Base::FileInfo fi(App::Application::getTempFileName().c_str()); + + // read in the ASCII file and write back to the file stream + Base::ofstream file(fi, std::ios::out | std::ios::binary); + if (reader) + reader >> file.rdbuf(); + file.close(); + + // read the shape from the temp file + myMesh->UNVToMesh(fi.filePath().c_str()); + + // delete the temp file + fi.deleteFile(); +} + +void FemMesh::transformGeometry(const Base::Matrix4D& rclTrf) +{ + //We perform a translation and rotation of the current active Mesh object + Base::Matrix4D clMatrix(rclTrf); + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + Base::Vector3d current_node; + for (;aNodeIter->more();) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + current_node.Set(aNode->X(),aNode->Y(),aNode->Z()); + current_node = clMatrix * current_node; + myMesh->GetMeshDS()->MoveNode(aNode,current_node.x,current_node.y,current_node.z); + } +} + +void FemMesh::setTransform(const Base::Matrix4D& rclTrf) +{ + // Placement handling, no geometric transformation + _Mtrx = rclTrf; +} + +Base::Matrix4D FemMesh::getTransform(void) const +{ + return _Mtrx; +} + +Base::BoundBox3d FemMesh::getBoundBox(void) const +{ + Base::BoundBox3d box; + + SMESHDS_Mesh* data = const_cast(getSMesh())->GetMeshDS(); + + SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator(); + for (;aNodeIter->more();) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = _Mtrx * vec; + box.Add(vec); + } + + return box; +} + +std::vector FemMesh::getElementTypes(void) const +{ + std::vector temp; + temp.push_back("Vertex"); + temp.push_back("Edge"); + temp.push_back("Face"); + temp.push_back("Volume"); + + return temp; +} + +unsigned long FemMesh::countSubElements(const char* Type) const +{ + return 0; +} + +Data::Segment* FemMesh::getSubElement(const char* Type, unsigned long n) const +{ + // FIXME implement subelement interface + //std::stringstream str; + //str << Type << n; + //std::string temp = str.str(); + //return new ShapeSegment(getSubShape(temp.c_str())); + return 0; +} + +struct Fem::FemMesh::FemMeshInfo FemMesh::getInfo(void) const{ + + struct FemMeshInfo rtrn; + + SMESHDS_Mesh* data = const_cast(getSMesh())->GetMeshDS(); + const SMDS_MeshInfo& info = data->GetMeshInfo(); + rtrn.numFaces = data->NbFaces(); + rtrn.numNode = info.NbNodes(); + rtrn.numTria = info.NbTriangles(); + rtrn.numQuad = info.NbQuadrangles(); + rtrn.numPoly = info.NbPolygons(); + rtrn.numVolu = info.NbVolumes(); + rtrn.numTetr = info.NbTetras(); + rtrn.numHexa = info.NbHexas(); + rtrn.numPyrd = info.NbPyramids(); + rtrn.numPris = info.NbPrisms(); + rtrn.numHedr = info.NbPolyhedrons(); + + return rtrn; + +} +// for(unsigned int i=0;iAddVolumeWithID( +// meshds->FindNode(all_elements[i][0]), +// meshds->FindNode(all_elements[i][2]), +// meshds->FindNode(all_elements[i][1]), +// meshds->FindNode(all_elements[i][3]), +// meshds->FindNode(all_elements[i][6]), +// meshds->FindNode(all_elements[i][5]), +// meshds->FindNode(all_elements[i][4]), +// meshds->FindNode(all_elements[i][9]), +// meshds->FindNode(all_elements[i][7]), +// meshds->FindNode(all_elements[i][8]), +// element_id[i] +// ); +// } + +Base::Quantity FemMesh::getVolume(void)const +{ + SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator(); + + //Calculate Mesh Volume + //For an accurate Volume Calculation of a quadratic Tetrahedron + //we have to calculate the Volume of 8 Sub-Tetrahedrons + Base::Vector3d a,b,c,a_b_product; + double volume = 0.0; + + for (;aVolIter->more();) + { + const SMDS_MeshVolume* aVol = aVolIter->next(); + + if ( aVol->NbNodes() != 10 ) continue; + + Base::Vector3d v1(aVol->GetNode(1)->X(),aVol->GetNode(1)->Y(),aVol->GetNode(1)->Z()); + Base::Vector3d v0(aVol->GetNode(0)->X(),aVol->GetNode(0)->Y(),aVol->GetNode(0)->Z()); + Base::Vector3d v2(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z()); + Base::Vector3d v3(aVol->GetNode(3)->X(),aVol->GetNode(3)->Y(),aVol->GetNode(3)->Z()); + Base::Vector3d v4(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z()); + Base::Vector3d v6(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z()); + Base::Vector3d v5(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z()); + Base::Vector3d v8(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z()); + Base::Vector3d v7(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z()); + Base::Vector3d v9(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z()); + + + //1,5,8,7 + a = v4 -v0 ; + b = v7 -v0 ; + c = v6 -v0 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //5,9,8,7 + a = v8 -v4 ; + b = v7 -v4 ; + c = v6 -v4 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //5,2,9,7 + a = v1 -v4 ; + b = v8 -v4 ; + c = v6 -v4 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //2,6,9,7 + a = v5 -v1 ; + b = v8 -v1 ; + c = v6 -v1 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //9,6,10,7 + a = v5 -v8 ; + b = v9 -v8 ; + c = v6 -v8 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //6,3,10,7 + a = v2 -v5 ; + b = v9 -v5 ; + c = v6 -v5 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //8,9,10,7 + a = v8 -v7 ; + b = v9 -v7 ; + c = v6 -v7 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + //8,9,10,4 + a = v8 -v7 ; + b = v9 -v7 ; + c = v3 -v7 ; + a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y; + volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); + + } + + return Base::Quantity(volume,Unit::Volume); + + +} diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 79d53fcfcb70..7515c1a93a75 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -1,163 +1,163 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_FEMMESH_H -#define FEM_FEMMESH_H - -#include -#include -#include - -#include -#include -#include - -class SMESH_Gen; -class SMESH_Mesh; -class SMESH_Hypothesis; -class TopoDS_Shape; -class TopoDS_Face; -class TopoDS_Edge; -class TopoDS_Vertex; -class TopoDS_Solid; - -namespace Fem -{ - -typedef boost::shared_ptr SMESH_HypothesisPtr; - -/** The representation of a FemMesh - */ -class AppFemExport FemMesh : public Data::ComplexGeoData -{ - TYPESYSTEM_HEADER(); - -public: - FemMesh(); - FemMesh(const FemMesh&); - ~FemMesh(); - - FemMesh &operator=(const FemMesh&); - const SMESH_Mesh* getSMesh() const; - SMESH_Mesh* getSMesh(); - SMESH_Gen * getGenerator(); - void addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp); - void setStanardHypotheses(); - void compute(); - - // from base class - virtual unsigned int getMemSize (void) const; - virtual void Save (Base::Writer &/*writer*/) const; - virtual void Restore(Base::XMLReader &/*reader*/); - void SaveDocFile (Base::Writer &writer) const; - void RestoreDocFile(Base::Reader &reader); - - /** @name Subelement management */ - //@{ - /** Sub type list - * List of different subelement types - * it is NOT a list of the subelements itself - */ - virtual std::vector getElementTypes(void) const; - virtual unsigned long countSubElements(const char* Type) const; - /// get the subelement by type and number - virtual Data::Segment* getSubElement(const char* Type, unsigned long) const; - //@} - - /** @name search and retrieval */ - //@{ - /// retrieving by region growing - std::set getSurfaceNodes(long ElemId, short FaceId, float Angle=360)const; - /// retrieving by solid - std::set getNodesBySolid(const TopoDS_Solid &solid) const; - /// retrieving by face - std::set getNodesByFace(const TopoDS_Face &face) const; - /// retrieving by edge - std::set getNodesByEdge(const TopoDS_Edge &edge) const; - /// retrieving by vertex - std::set getNodesByVertex(const TopoDS_Vertex &vertex) const; - /// retrieving node IDs by element ID - std::list getElementNodes(int id) const; - /// retrieving volume IDs and face IDs number by face - std::list > getVolumesByFace(const TopoDS_Face &face) const; - /// retrieving volume IDs and CalculiX face number by face - std::map getccxVolumesByFace(const TopoDS_Face &face) const; - //@} - - /** @name Placement control */ - //@{ - /// set the transformation - void setTransform(const Base::Matrix4D& rclTrf); - /// get the transformation - Base::Matrix4D getTransform(void) const; - /// Bound box from the shape - Base::BoundBox3d getBoundBox(void)const; - /// get the volume (when there are volume elements) - Base::Quantity getVolume(void)const; - //@} - - /** @name Modification */ - //@{ - /// Applies a transformation on the real geometric data type - void transformGeometry(const Base::Matrix4D &rclMat); - //@} - - struct FemMeshInfo { - int numFaces; - int numNode; - int numTria; - int numQuad; - int numPoly; - int numVolu; - int numTetr; - int numHexa; - int numPyrd; - int numPris; - int numHedr; - }; - - /// - struct FemMeshInfo getInfo(void) const; - - /// import from files - void read(const char *FileName); - void write(const char *FileName) const; - void writeABAQUS(const std::string &Filename) const; - -private: - void copyMeshData(const FemMesh&); - void readNastran(const std::string &Filename); - -private: - /// positioning matrix - Base::Matrix4D _Mtrx; - SMESH_Gen *myGen; - SMESH_Mesh *myMesh; - - std::list hypoth; -}; - -} //namespace Part - - -#endif // FEM_FEMMESH_H +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_FEMMESH_H +#define FEM_FEMMESH_H + +#include +#include +#include + +#include +#include +#include + +class SMESH_Gen; +class SMESH_Mesh; +class SMESH_Hypothesis; +class TopoDS_Shape; +class TopoDS_Face; +class TopoDS_Edge; +class TopoDS_Vertex; +class TopoDS_Solid; + +namespace Fem +{ + +typedef boost::shared_ptr SMESH_HypothesisPtr; + +/** The representation of a FemMesh + */ +class AppFemExport FemMesh : public Data::ComplexGeoData +{ + TYPESYSTEM_HEADER(); + +public: + FemMesh(); + FemMesh(const FemMesh&); + ~FemMesh(); + + FemMesh &operator=(const FemMesh&); + const SMESH_Mesh* getSMesh() const; + SMESH_Mesh* getSMesh(); + SMESH_Gen * getGenerator(); + void addHypothesis(const TopoDS_Shape & aSubShape, SMESH_HypothesisPtr hyp); + void setStanardHypotheses(); + void compute(); + + // from base class + virtual unsigned int getMemSize (void) const; + virtual void Save (Base::Writer &/*writer*/) const; + virtual void Restore(Base::XMLReader &/*reader*/); + void SaveDocFile (Base::Writer &writer) const; + void RestoreDocFile(Base::Reader &reader); + + /** @name Subelement management */ + //@{ + /** Sub type list + * List of different subelement types + * it is NOT a list of the subelements itself + */ + virtual std::vector getElementTypes(void) const; + virtual unsigned long countSubElements(const char* Type) const; + /// get the subelement by type and number + virtual Data::Segment* getSubElement(const char* Type, unsigned long) const; + //@} + + /** @name search and retrieval */ + //@{ + /// retrieving by region growing + std::set getSurfaceNodes(long ElemId, short FaceId, float Angle=360)const; + /// retrieving by solid + std::set getNodesBySolid(const TopoDS_Solid &solid) const; + /// retrieving by face + std::set getNodesByFace(const TopoDS_Face &face) const; + /// retrieving by edge + std::set getNodesByEdge(const TopoDS_Edge &edge) const; + /// retrieving by vertex + std::set getNodesByVertex(const TopoDS_Vertex &vertex) const; + /// retrieving node IDs by element ID + std::list getElementNodes(int id) const; + /// retrieving volume IDs and face IDs number by face + std::list > getVolumesByFace(const TopoDS_Face &face) const; + /// retrieving volume IDs and CalculiX face number by face + std::map getccxVolumesByFace(const TopoDS_Face &face) const; + //@} + + /** @name Placement control */ + //@{ + /// set the transformation + void setTransform(const Base::Matrix4D& rclTrf); + /// get the transformation + Base::Matrix4D getTransform(void) const; + /// Bound box from the shape + Base::BoundBox3d getBoundBox(void)const; + /// get the volume (when there are volume elements) + Base::Quantity getVolume(void)const; + //@} + + /** @name Modification */ + //@{ + /// Applies a transformation on the real geometric data type + void transformGeometry(const Base::Matrix4D &rclMat); + //@} + + struct FemMeshInfo { + int numFaces; + int numNode; + int numTria; + int numQuad; + int numPoly; + int numVolu; + int numTetr; + int numHexa; + int numPyrd; + int numPris; + int numHedr; + }; + + /// + struct FemMeshInfo getInfo(void) const; + + /// import from files + void read(const char *FileName); + void write(const char *FileName) const; + void writeABAQUS(const std::string &Filename) const; + +private: + void copyMeshData(const FemMesh&); + void readNastran(const std::string &Filename); + +private: + /// positioning matrix + Base::Matrix4D _Mtrx; + SMESH_Gen *myGen; + SMESH_Mesh *myMesh; + + std::list hypoth; +}; + +} //namespace Part + + +#endif // FEM_FEMMESH_H diff --git a/src/Mod/Fem/App/FemMeshObject.cpp b/src/Mod/Fem/App/FemMeshObject.cpp index e14d2bd186cf..d1974b73a7ee 100644 --- a/src/Mod/Fem/App/FemMeshObject.cpp +++ b/src/Mod/Fem/App/FemMeshObject.cpp @@ -1,72 +1,72 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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_ -#endif - -#include "FemMeshObject.h" -#include "FemMesh.h" -#include -#include - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemMeshObject, App::GeoFeature) - - -FemMeshObject::FemMeshObject() -{ - ADD_PROPERTY_TYPE(FemMesh,(), "FEM Mesh",Prop_None,"FEM Mesh object"); -} - -FemMeshObject::~FemMeshObject() -{ -} - -short FemMeshObject::mustExecute(void) const -{ - return 0; -} - -PyObject *FemMeshObject::getPyObject() -{ - if (PythonObject.is(Py::_None())){ - // ref counter is set to 1 - PythonObject = Py::Object(new DocumentObjectPy(this),true); - } - return Py::new_reference_to(PythonObject); -} - -void FemMeshObject::onChanged(const Property* prop) -{ - App::GeoFeature::onChanged(prop); - - // if the placement has changed apply the change to the mesh data as well - if (prop == &this->Placement) { - const_cast(this->FemMesh.getValue()).setTransform(this->Placement.getValue().toMatrix()); - } - -} +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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_ +#endif + +#include "FemMeshObject.h" +#include "FemMesh.h" +#include +#include + +using namespace Fem; +using namespace App; + +PROPERTY_SOURCE(Fem::FemMeshObject, App::GeoFeature) + + +FemMeshObject::FemMeshObject() +{ + ADD_PROPERTY_TYPE(FemMesh,(), "FEM Mesh",Prop_None,"FEM Mesh object"); +} + +FemMeshObject::~FemMeshObject() +{ +} + +short FemMeshObject::mustExecute(void) const +{ + return 0; +} + +PyObject *FemMeshObject::getPyObject() +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new DocumentObjectPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +void FemMeshObject::onChanged(const Property* prop) +{ + App::GeoFeature::onChanged(prop); + + // if the placement has changed apply the change to the mesh data as well + if (prop == &this->Placement) { + const_cast(this->FemMesh.getValue()).setTransform(this->Placement.getValue().toMatrix()); + } + +} diff --git a/src/Mod/Fem/App/FemMeshObject.h b/src/Mod/Fem/App/FemMeshObject.h index 75c245228466..0a774c0605dc 100644 --- a/src/Mod/Fem/App/FemMeshObject.h +++ b/src/Mod/Fem/App/FemMeshObject.h @@ -1,66 +1,66 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 * - * * - ***************************************************************************/ - - -#ifndef Fem_FemMeshObject_H -#define Fem_FemMeshObject_H - -#include -#include -#include - -#include "FemMesh.h" -#include "FemMeshProperty.h" - -namespace Fem -{ - -class AppFemExport FemMeshObject : public App::GeoFeature -{ - PROPERTY_HEADER(Fem::FemMeshObject); - -public: - /// Constructor - FemMeshObject(void); - virtual ~FemMeshObject(); - - /// returns the type name of the ViewProvider - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemMesh"; - } - virtual App::DocumentObjectExecReturn *execute(void) { - return App::DocumentObject::StdReturn; - } - virtual short mustExecute(void) const; - virtual PyObject *getPyObject(void); - - PropertyFemMesh FemMesh; - -protected: - /// get called by the container when a property has changed - virtual void onChanged (const App::Property* prop); -}; - -} //namespace Fem - - -#endif // Fem_FemMeshObject_H +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 * + * * + ***************************************************************************/ + + +#ifndef Fem_FemMeshObject_H +#define Fem_FemMeshObject_H + +#include +#include +#include + +#include "FemMesh.h" +#include "FemMeshProperty.h" + +namespace Fem +{ + +class AppFemExport FemMeshObject : public App::GeoFeature +{ + PROPERTY_HEADER(Fem::FemMeshObject); + +public: + /// Constructor + FemMeshObject(void); + virtual ~FemMeshObject(); + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemMesh"; + } + virtual App::DocumentObjectExecReturn *execute(void) { + return App::DocumentObject::StdReturn; + } + virtual short mustExecute(void) const; + virtual PyObject *getPyObject(void); + + PropertyFemMesh FemMesh; + +protected: + /// get called by the container when a property has changed + virtual void onChanged (const App::Property* prop); +}; + +} //namespace Fem + + +#endif // Fem_FemMeshObject_H diff --git a/src/Mod/Fem/App/FemMeshProperty.cpp b/src/Mod/Fem/App/FemMeshProperty.cpp index 43e269ad11e9..f2598de5c38e 100644 --- a/src/Mod/Fem/App/FemMeshProperty.cpp +++ b/src/Mod/Fem/App/FemMeshProperty.cpp @@ -1,157 +1,157 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * - * * - * 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 -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FemMeshProperty.h" -#include "FemMeshPy.h" - -using namespace Fem; - -TYPESYSTEM_SOURCE(Fem::PropertyFemMesh , App::PropertyComplexGeoData); - -PropertyFemMesh::PropertyFemMesh() : _FemMesh(new FemMesh) -{ -} - -PropertyFemMesh::~PropertyFemMesh() -{ -} - -void PropertyFemMesh::setValuePtr(FemMesh* mesh) -{ - // use the tmp. object to guarantee that the referenced mesh is not destroyed - // before calling hasSetValue() - Base::Reference tmp(_FemMesh); - aboutToSetValue(); - _FemMesh = mesh; - hasSetValue(); -} - -void PropertyFemMesh::setValue(const FemMesh& sh) -{ - aboutToSetValue(); - *_FemMesh = sh; - hasSetValue(); -} - -const FemMesh &PropertyFemMesh::getValue(void)const -{ - return *_FemMesh; -} - -const Data::ComplexGeoData* PropertyFemMesh::getComplexData() const -{ - return (FemMesh*)_FemMesh; -} - -Base::BoundBox3d PropertyFemMesh::getBoundingBox() const -{ - return _FemMesh->getBoundBox(); -} - -void PropertyFemMesh::transformGeometry(const Base::Matrix4D &rclMat) -{ - aboutToSetValue(); - _FemMesh->transformGeometry(rclMat); - hasSetValue(); -} - -PyObject *PropertyFemMesh::getPyObject(void) -{ - FemMeshPy* mesh = new FemMeshPy(&*_FemMesh); - mesh->setConst(); - return mesh; -} - -void PropertyFemMesh::setPyObject(PyObject *value) -{ - if (PyObject_TypeCheck(value, &(FemMeshPy::Type))) { - FemMeshPy *pcObject = static_cast(value); - setValue(*pcObject->getFemMeshPtr()); - } - else if (PyObject_TypeCheck(value, &(Base::PlacementPy::Type))) { - Base::PlacementPy *pcObject = static_cast(value); - transformGeometry(pcObject->getPlacementPtr()->toMatrix()); - } - else { - std::string error = std::string("type must be 'FemMesh', not "); - error += value->ob_type->tp_name; - throw Base::TypeError(error); - } -} - -App::Property *PropertyFemMesh::Copy(void) const -{ - PropertyFemMesh *prop = new PropertyFemMesh(); - prop->_FemMesh = this->_FemMesh; - return prop; -} - -void PropertyFemMesh::Paste(const App::Property &from) -{ - aboutToSetValue(); - _FemMesh = dynamic_cast(from)._FemMesh; - hasSetValue(); -} - -unsigned int PropertyFemMesh::getMemSize (void) const -{ - return _FemMesh->getMemSize(); -} - -void PropertyFemMesh::Save (Base::Writer &writer) const -{ - _FemMesh->Save(writer); -} - -void PropertyFemMesh::Restore(Base::XMLReader &reader) -{ - _FemMesh->Restore(reader); -} - -void PropertyFemMesh::SaveDocFile (Base::Writer &writer) const -{ - _FemMesh->SaveDocFile(writer); -} - -void PropertyFemMesh::RestoreDocFile(Base::Reader &reader ) -{ - aboutToSetValue(); - _FemMesh->RestoreDocFile(reader); - hasSetValue(); -} +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * * + * 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 +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FemMeshProperty.h" +#include "FemMeshPy.h" + +using namespace Fem; + +TYPESYSTEM_SOURCE(Fem::PropertyFemMesh , App::PropertyComplexGeoData); + +PropertyFemMesh::PropertyFemMesh() : _FemMesh(new FemMesh) +{ +} + +PropertyFemMesh::~PropertyFemMesh() +{ +} + +void PropertyFemMesh::setValuePtr(FemMesh* mesh) +{ + // use the tmp. object to guarantee that the referenced mesh is not destroyed + // before calling hasSetValue() + Base::Reference tmp(_FemMesh); + aboutToSetValue(); + _FemMesh = mesh; + hasSetValue(); +} + +void PropertyFemMesh::setValue(const FemMesh& sh) +{ + aboutToSetValue(); + *_FemMesh = sh; + hasSetValue(); +} + +const FemMesh &PropertyFemMesh::getValue(void)const +{ + return *_FemMesh; +} + +const Data::ComplexGeoData* PropertyFemMesh::getComplexData() const +{ + return (FemMesh*)_FemMesh; +} + +Base::BoundBox3d PropertyFemMesh::getBoundingBox() const +{ + return _FemMesh->getBoundBox(); +} + +void PropertyFemMesh::transformGeometry(const Base::Matrix4D &rclMat) +{ + aboutToSetValue(); + _FemMesh->transformGeometry(rclMat); + hasSetValue(); +} + +PyObject *PropertyFemMesh::getPyObject(void) +{ + FemMeshPy* mesh = new FemMeshPy(&*_FemMesh); + mesh->setConst(); + return mesh; +} + +void PropertyFemMesh::setPyObject(PyObject *value) +{ + if (PyObject_TypeCheck(value, &(FemMeshPy::Type))) { + FemMeshPy *pcObject = static_cast(value); + setValue(*pcObject->getFemMeshPtr()); + } + else if (PyObject_TypeCheck(value, &(Base::PlacementPy::Type))) { + Base::PlacementPy *pcObject = static_cast(value); + transformGeometry(pcObject->getPlacementPtr()->toMatrix()); + } + else { + std::string error = std::string("type must be 'FemMesh', not "); + error += value->ob_type->tp_name; + throw Base::TypeError(error); + } +} + +App::Property *PropertyFemMesh::Copy(void) const +{ + PropertyFemMesh *prop = new PropertyFemMesh(); + prop->_FemMesh = this->_FemMesh; + return prop; +} + +void PropertyFemMesh::Paste(const App::Property &from) +{ + aboutToSetValue(); + _FemMesh = dynamic_cast(from)._FemMesh; + hasSetValue(); +} + +unsigned int PropertyFemMesh::getMemSize (void) const +{ + return _FemMesh->getMemSize(); +} + +void PropertyFemMesh::Save (Base::Writer &writer) const +{ + _FemMesh->Save(writer); +} + +void PropertyFemMesh::Restore(Base::XMLReader &reader) +{ + _FemMesh->Restore(reader); +} + +void PropertyFemMesh::SaveDocFile (Base::Writer &writer) const +{ + _FemMesh->SaveDocFile(writer); +} + +void PropertyFemMesh::RestoreDocFile(Base::Reader &reader ) +{ + aboutToSetValue(); + _FemMesh->RestoreDocFile(reader); + hasSetValue(); +} diff --git a/src/Mod/Fem/App/FemMeshProperty.h b/src/Mod/Fem/App/FemMeshProperty.h index 444d811e66a6..f3a3123e24dc 100644 --- a/src/Mod/Fem/App/FemMeshProperty.h +++ b/src/Mod/Fem/App/FemMeshProperty.h @@ -1,93 +1,93 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2008 * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef Fem_PropertyFemMesh_H -#define Fem_PropertyFemMesh_H - -#include "FemMesh.h" -#include -#include - -namespace Fem -{ - - -/** The part shape property class. - * @author Werner Mayer - */ -class AppFemExport PropertyFemMesh : public App::PropertyComplexGeoData -{ - TYPESYSTEM_HEADER(); - -public: - PropertyFemMesh(); - ~PropertyFemMesh(); - - /** @name Getter/setter */ - //@{ - void setValuePtr(FemMesh* mesh); - /// set the FemMesh shape - void setValue(const FemMesh&); - /// does nothing, for add property macro - void setValue(void){}; - /// get the FemMesh shape - const FemMesh &getValue(void) const; - const Data::ComplexGeoData* getComplexData() const; - //@} - - - /** @name Getting basic geometric entities */ - //@{ - /** Returns the bounding box around the underlying mesh kernel */ - Base::BoundBox3d getBoundingBox() const; - void transformGeometry(const Base::Matrix4D &rclMat); - //@} - - /** @name Python interface */ - //@{ - PyObject* getPyObject(void); - void setPyObject(PyObject *value); - //@} - - /** @name Save/restore */ - //@{ - void Save (Base::Writer &writer) const; - void Restore(Base::XMLReader &reader); - void SaveDocFile (Base::Writer &writer) const; - void RestoreDocFile(Base::Reader &reader); - - App::Property *Copy(void) const; - void Paste(const App::Property &from); - unsigned int getMemSize (void) const; - const char* getEditorName(void) const { return "FemGui::PropertyFemMeshItem"; } - //@} - -private: - Base::Reference _FemMesh; -}; - - -} //namespace Fem - - -#endif // PROPERTYTOPOSHAPE_H +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2008 * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef Fem_PropertyFemMesh_H +#define Fem_PropertyFemMesh_H + +#include "FemMesh.h" +#include +#include + +namespace Fem +{ + + +/** The part shape property class. + * @author Werner Mayer + */ +class AppFemExport PropertyFemMesh : public App::PropertyComplexGeoData +{ + TYPESYSTEM_HEADER(); + +public: + PropertyFemMesh(); + ~PropertyFemMesh(); + + /** @name Getter/setter */ + //@{ + void setValuePtr(FemMesh* mesh); + /// set the FemMesh shape + void setValue(const FemMesh&); + /// does nothing, for add property macro + void setValue(void){}; + /// get the FemMesh shape + const FemMesh &getValue(void) const; + const Data::ComplexGeoData* getComplexData() const; + //@} + + + /** @name Getting basic geometric entities */ + //@{ + /** Returns the bounding box around the underlying mesh kernel */ + Base::BoundBox3d getBoundingBox() const; + void transformGeometry(const Base::Matrix4D &rclMat); + //@} + + /** @name Python interface */ + //@{ + PyObject* getPyObject(void); + void setPyObject(PyObject *value); + //@} + + /** @name Save/restore */ + //@{ + void Save (Base::Writer &writer) const; + void Restore(Base::XMLReader &reader); + void SaveDocFile (Base::Writer &writer) const; + void RestoreDocFile(Base::Reader &reader); + + App::Property *Copy(void) const; + void Paste(const App::Property &from); + unsigned int getMemSize (void) const; + const char* getEditorName(void) const { return "FemGui::PropertyFemMeshItem"; } + //@} + +private: + Base::Reference _FemMesh; +}; + + +} //namespace Fem + + +#endif // PROPERTYTOPOSHAPE_H diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index 378ccc95e6a6..450ecbd5de61 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -1,242 +1,242 @@ - - - - - - FemMesh class - - - - set the Part shape to mesh - - - - - Update the internal mesh structure - - - - - Add hypothesis - - - - - Set some standard hypotheses for the whole shape - - - - - Add a node by setting (x,y,z). - - - - - Add an edge by setting two node indices. - - - - - Add a face by setting three node indices. - - - - - Add a quad by setting four node indices. - - - - - Add a volume by setting an arbitrary number of node indices. - - - - - Read in an DAT, UNV, MED or STL file. - - - - - write out an DAT, UNV, MED or STL file. - - - - - write out as ABAQUS. - - - - - Use a Placement object to perform a translation or rotation - - - - - Make a copy of this FEM mesh. - - - - - Return a dict of volume IDs and face IDs which belong to a TopoFace - - - - - Return a dict of volume IDs and ccx face numbers which belong to a TopoFace - - - - - Get the node position vector by an Node-ID - - - - - Return a list of node IDs which belong to a TopoSolid - - - - - Return a list of node IDs which belong to a TopoFace - - - - - Return a list of node IDs which belong to a TopoEdge - - - - - Return a list of node IDs which belong to a TopoVertex - - - - - Return a tuple of node IDs to a given element ID - - - - - Dictionary of Nodes by ID (int ID:Vector()) - - - - - - Number of nodes in the Mesh. - - - - - - Tuple of edge IDs - - - - - - Number of edges in the Mesh. - - - - - - Tuple of face IDs - - - - - - Number of Faces in the Mesh. - - - - - - Number of Triangles in the Mesh. - - - - - - Number of Quadrangles in the Mesh. - - - - - - Number of Quadrangles in the Mesh. - - - - - - Tuple of volume IDs - - - - - - Number of Volumes in the Mesh. - - - - - - Number of Tetras in the Mesh. - - - - - - Number of Hexas in the Mesh. - - - - - - Number of Pyramids in the Mesh. - - - - - - Number of Prisms in the Mesh. - - - - - - Number of Polyhedrons in the Mesh. - - - - - - Number of SubMeshs in the Mesh. - - - - - - Number of Groups in the Mesh. - - - - - - Volume of the mesh. - - - - - + + + + + + FemMesh class + + + + set the Part shape to mesh + + + + + Update the internal mesh structure + + + + + Add hypothesis + + + + + Set some standard hypotheses for the whole shape + + + + + Add a node by setting (x,y,z). + + + + + Add an edge by setting two node indices. + + + + + Add a face by setting three node indices. + + + + + Add a quad by setting four node indices. + + + + + Add a volume by setting an arbitrary number of node indices. + + + + + Read in an DAT, UNV, MED or STL file. + + + + + write out an DAT, UNV, MED or STL file. + + + + + write out as ABAQUS. + + + + + Use a Placement object to perform a translation or rotation + + + + + Make a copy of this FEM mesh. + + + + + Return a dict of volume IDs and face IDs which belong to a TopoFace + + + + + Return a dict of volume IDs and ccx face numbers which belong to a TopoFace + + + + + Get the node position vector by an Node-ID + + + + + Return a list of node IDs which belong to a TopoSolid + + + + + Return a list of node IDs which belong to a TopoFace + + + + + Return a list of node IDs which belong to a TopoEdge + + + + + Return a list of node IDs which belong to a TopoVertex + + + + + Return a tuple of node IDs to a given element ID + + + + + Dictionary of Nodes by ID (int ID:Vector()) + + + + + + Number of nodes in the Mesh. + + + + + + Tuple of edge IDs + + + + + + Number of edges in the Mesh. + + + + + + Tuple of face IDs + + + + + + Number of Faces in the Mesh. + + + + + + Number of Triangles in the Mesh. + + + + + + Number of Quadrangles in the Mesh. + + + + + + Number of Quadrangles in the Mesh. + + + + + + Tuple of volume IDs + + + + + + Number of Volumes in the Mesh. + + + + + + Number of Tetras in the Mesh. + + + + + + Number of Hexas in the Mesh. + + + + + + Number of Pyramids in the Mesh. + + + + + + Number of Prisms in the Mesh. + + + + + + Number of Polyhedrons in the Mesh. + + + + + + Number of SubMeshs in the Mesh. + + + + + + Number of Groups in the Mesh. + + + + + + Volume of the mesh. + + + + + diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index aca522a8e373..a37cd3fdb424 100644 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -1,962 +1,962 @@ -/*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * - * * - * 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" -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "Mod/Fem/App/FemMesh.h" - -// inclusion of the generated files (generated out of FemMeshPy.xml) -#include "FemMeshPy.h" -#include "FemMeshPy.cpp" -#include "HypothesisPy.h" - -using namespace Fem; - -// returns a string which represents the object e.g. when printed in python -std::string FemMeshPy::representation(void) const -{ - std::stringstream str; - getFemMeshPtr()->getSMesh()->Dump(str); - return str.str(); -} - -PyObject *FemMeshPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper -{ - // create a new instance of FemMeshPy and the Twin object - return new FemMeshPy(new FemMesh); -} - -// constructor method -int FemMeshPy::PyInit(PyObject* args, PyObject* /*kwd*/) -{ - PyObject *pcObj=0; - if (!PyArg_ParseTuple(args, "|O", &pcObj)) // convert args: Python->C - return -1; // NULL triggers exception - - try { - // if no mesh is given - if (!pcObj) return 0; - if (PyObject_TypeCheck(pcObj, &(FemMeshPy::Type))) { - getFemMeshPtr()->operator= (*static_cast(pcObj)->getFemMeshPtr()); - } - else { - PyErr_Format(PyExc_TypeError, "Cannot create a FemMesh out of a '%s'", - pcObj->ob_type->tp_name); - return -1; - } - } - catch (const Base::Exception &e) { - PyErr_SetString(Base::BaseExceptionFreeCADError,e.what()); - return -1; - } - catch (const std::exception &e) { - PyErr_SetString(Base::BaseExceptionFreeCADError,e.what()); - return -1; - } - catch (const Py::Exception&) { - return -1; - } - - return 0; -} - - -// ===== Methods ============================================================ - -PyObject* FemMeshPy::setShape(PyObject *args) -{ - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) - return 0; - - try { - TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->_Shape; - getFemMeshPtr()->getSMesh()->ShapeToMesh(shape); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::addHypothesis(PyObject *args) -{ - PyObject* hyp; - PyObject* shp=0; - // Since we have not a common base class for the Python binding of the - // hypotheses classes we cannot pass a certain Python type - if (!PyArg_ParseTuple(args, "O|O!",&hyp, &(Part::TopoShapePy::Type), &shp)) - return 0; - - TopoDS_Shape shape; - if (shp == 0) - shape = getFemMeshPtr()->getSMesh()->GetShapeToMesh(); - else - shape = static_cast(shp)->getTopoShapePtr()->_Shape; - - try { - Py::Object obj(hyp); - Fem::Hypothesis attr(obj.getAttr("this")); - SMESH_HypothesisPtr thesis = attr.extensionObject()->getHypothesis(); - getFemMeshPtr()->addHypothesis(shape, thesis); - } - catch (const Py::Exception&) { - return 0; - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::setStanardHypotheses(PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return 0; - - try { - getFemMeshPtr()->setStanardHypotheses(); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::compute(PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return 0; - - try { - getFemMeshPtr()->compute(); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::addNode(PyObject *args) -{ - double x,y,z; - int i = -1; - if (PyArg_ParseTuple(args, "ddd",&x,&y,&z)){ - try { - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - SMDS_MeshNode* node = meshDS->AddNode(x,y,z); - if (!node) - throw std::runtime_error("Failed to add node"); - return Py::new_reference_to(Py::Int(node->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - } - PyErr_Clear(); - - if (PyArg_ParseTuple(args, "dddi",&x,&y,&z,&i)){ - try { - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - SMDS_MeshNode* node = meshDS->AddNodeWithID(x,y,z,i); - if (!node) - throw std::runtime_error("Failed to add node"); - return Py::new_reference_to(Py::Int(node->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - } - PyErr_SetString(PyExc_TypeError, "addNode() accepts:\n" - "-- addNode(x,y,z)\n" - "-- addNode(x,y,z,ElemId)\n"); - return 0; - -} - -PyObject* FemMeshPy::addEdge(PyObject *args) -{ - int n1,n2; - if (!PyArg_ParseTuple(args, "ii",&n1,&n2)) - return 0; - - try { - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - const SMDS_MeshNode* node1 = meshDS->FindNode(n1); - const SMDS_MeshNode* node2 = meshDS->FindNode(n2); - if (!node1 || !node2) - throw std::runtime_error("Failed to get node of the given indices"); - SMDS_MeshEdge* edge = meshDS->AddEdge(node1, node2); - if (!edge) - throw std::runtime_error("Failed to add edge"); - return Py::new_reference_to(Py::Int(edge->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } -} - -PyObject* FemMeshPy::addFace(PyObject *args) -{ - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - - int n1,n2,n3; - if (PyArg_ParseTuple(args, "iii",&n1,&n2,&n3)) - { - // old form, deprecated - try { - const SMDS_MeshNode* node1 = meshDS->FindNode(n1); - const SMDS_MeshNode* node2 = meshDS->FindNode(n2); - const SMDS_MeshNode* node3 = meshDS->FindNode(n3); - if (!node1 || !node2 || !node3) - throw std::runtime_error("Failed to get node of the given indices"); - SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3); - if (!face) - throw std::runtime_error("Failed to add face"); - return Py::new_reference_to(Py::Int(face->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - } - PyErr_Clear(); - - PyObject *obj; - int ElementId=-1; - if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) - { - Py::List list(obj); - std::vector Nodes; - for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { - Py::Int NoNr(*it); - const SMDS_MeshNode* node = meshDS->FindNode(NoNr); - if (!node) - throw std::runtime_error("Failed to get node of the given indices"); - Nodes.push_back(node); - } - - SMDS_MeshFace* face=0; - switch(Nodes.size()){ - case 3: - face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2]); - if (!face) - throw std::runtime_error("Failed to add triangular face"); - break; - case 4: - face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3]); - if (!face) - throw std::runtime_error("Failed to add face"); - break; - case 6: - face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5]); - if (!face) - throw std::runtime_error("Failed to add face"); - break; - case 8: - face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7]); - if (!face) - throw std::runtime_error("Failed to add face"); - break; - default: - throw std::runtime_error("Unknown node count, [3|4|6|8] are allowed"); //unknown face type - } - - return Py::new_reference_to(Py::Int(face->GetID())); - - } - - PyErr_SetString(PyExc_TypeError, "addFace accepts:\n" - "-- int,int,int\n" - "-- [3|4|6|8 int],[int]\n"); - return 0; -} - -PyObject* FemMeshPy::addQuad(PyObject *args) -{ - int n1,n2,n3,n4; - if (!PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4)) - return 0; - - try { - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - const SMDS_MeshNode* node1 = meshDS->FindNode(n1); - const SMDS_MeshNode* node2 = meshDS->FindNode(n2); - const SMDS_MeshNode* node3 = meshDS->FindNode(n3); - const SMDS_MeshNode* node4 = meshDS->FindNode(n4); - if (!node1 || !node2 || !node3 || !node4) - throw std::runtime_error("Failed to get node of the given indices"); - SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3, node4); - if (!face) - throw std::runtime_error("Failed to add quad"); - return Py::new_reference_to(Py::Int(face->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } -} - -PyObject* FemMeshPy::addVolume(PyObject *args) -{ - SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); - SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); - - int n1,n2,n3,n4; - if (PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4)) - { - try { - const SMDS_MeshNode* node1 = meshDS->FindNode(n1); - const SMDS_MeshNode* node2 = meshDS->FindNode(n2); - const SMDS_MeshNode* node3 = meshDS->FindNode(n3); - const SMDS_MeshNode* node4 = meshDS->FindNode(n4); - if (!node1 || !node2 || !node3 || !node4) - throw std::runtime_error("Failed to get node of the given indices"); - SMDS_MeshVolume* vol = meshDS->AddVolume(node1, node2, node3, node4); - if (!vol) - throw std::runtime_error("Failed to add volume"); - return Py::new_reference_to(Py::Int(vol->GetID())); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - } - PyErr_Clear(); - - PyObject *obj; - int ElementId=-1; - if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) - { - Py::List list(obj); - std::vector Nodes; - for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { - Py::Int NoNr(*it); - const SMDS_MeshNode* node = meshDS->FindNode(NoNr); - if (!node) - throw std::runtime_error("Failed to get node of the given indices"); - Nodes.push_back(node); - } - - SMDS_MeshVolume* vol=0; - if(ElementId != -1) { - switch(Nodes.size()){ - case 4: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Tet4 volume"); - break; - case 5: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Pyra5 volume"); - break; - case 6: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Penta6 volume"); - break; - case 8: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Hexa8 volume"); - break; - case 10: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Tet10 volume"); - break; - case 13: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Pyra13 volume"); - case 15: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Penta15 volume"); - case 20: - vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],Nodes[15],Nodes[16],Nodes[17],Nodes[18],Nodes[19],ElementId); - if (!vol) - throw std::runtime_error("Failed to add Hexa20 volume"); - break; - - default: throw std::runtime_error("Unknown node count, [4|5|6|8|10|13|15|20] are allowed"); //unknown volume type - } - }else{ - switch(Nodes.size()){ - case 4: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3]); - if (!vol) - throw std::runtime_error("Failed to add Tet4 volume"); - break; - case 5: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4]); - if (!vol) - throw std::runtime_error("Failed to add Pyra5 volume"); - break; - case 6: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5]); - if (!vol) - throw std::runtime_error("Failed to add Penta6 volume"); - break; - case 8: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7]); - if (!vol) - throw std::runtime_error("Failed to add Hexa8 volume"); - break; - case 10: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9]); - if (!vol) - throw std::runtime_error("Failed to add Tet10 volume"); - break; - case 13: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12]); - if (!vol) - throw std::runtime_error("Failed to add Pyra13 volume"); - break; - case 15: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14]); - if (!vol) - throw std::runtime_error("Failed to add Penta15 volume"); - break; - case 20: - vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],Nodes[15],Nodes[16],Nodes[17],Nodes[18],Nodes[19]); - if (!vol) - throw std::runtime_error("Failed to add Hexa20 volume"); - break; - - default: throw std::runtime_error("Unknown node count, [4|5|6|8|10|13|15|20] are allowed"); //unknown volume type - } - - } - - return Py::new_reference_to(Py::Int(vol->GetID())); - - } - - PyErr_SetString(PyExc_TypeError, "addVolume accepts:\n" - "-- int,int,int,int\n" - "-- [4|5|6|8|10|13|15|20 int],[int]\n"); - return 0; - -} - -PyObject* FemMeshPy::copy(PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return 0; - - const FemMesh& mesh = *getFemMeshPtr(); - return new FemMeshPy(new FemMesh(mesh)); -} - -PyObject* FemMeshPy::read(PyObject *args) -{ - char* Name; - if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) - return 0; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - try { - getFemMeshPtr()->read(EncodedName.c_str()); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::write(PyObject *args) -{ - char* Name; - if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) - return 0; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - try { - getFemMeshPtr()->write(EncodedName.c_str()); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::writeABAQUS(PyObject *args) -{ - char* Name; - if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) - return 0; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - try { - getFemMeshPtr()->writeABAQUS(EncodedName.c_str()); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::setTransform(PyObject *args) -{ - PyObject* ptr; - if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &ptr)) - return 0; - - try { - Base::Placement* placement = static_cast(ptr)->getPlacementPtr(); - Base::Matrix4D mat = placement->toMatrix(); - getFemMeshPtr()->transformGeometry(mat); - } - catch (const std::exception& e) { - PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); - return 0; - } - Py_Return; -} - -PyObject* FemMeshPy::getVolumesByFace(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); - return 0; - } - - const TopoDS_Face& fc = TopoDS::Face(sh); - - Py::List ret; - std::list > resultSet = getFemMeshPtr()->getVolumesByFace(fc); - for (std::list >::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { - Py::Tuple vol_face(2); - vol_face.setItem(0, Py::Int(it->first)); - vol_face.setItem(1, Py::Int(it->second)); - ret.append(vol_face); - } - - return Py::new_reference_to(ret); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getccxVolumesByFace(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); - return 0; - } - - const TopoDS_Face& fc = TopoDS::Face(sh); - - Py::List ret; - std::map resultSet = getFemMeshPtr()->getccxVolumesByFace(fc); - for (std::map::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { - Py::Tuple vol_face(2); - vol_face.setItem(0, Py::Int(it->first)); - vol_face.setItem(1, Py::Int(it->second)); - ret.append(vol_face); - } - - return Py::new_reference_to(ret); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getNodeById(PyObject *args) -{ - int id; - if (!PyArg_ParseTuple(args, "i", &id)) - return 0; - - Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); - const SMDS_MeshNode* aNode = getFemMeshPtr()->getSMesh()->GetMeshDS()->FindNode(id); - - if(aNode){ - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - vec = Mtrx * vec; - return new Base::VectorPy( vec ); - }else{ - PyErr_SetString(Base::BaseExceptionFreeCADError, "No valid ID"); - return 0; - } -} - -PyObject* FemMeshPy::getNodesBySolid(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeSolidPy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - const TopoDS_Solid& fc = TopoDS::Solid(sh); - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Solid is empty"); - return 0; - } - Py::List ret; - std::set resultSet = getFemMeshPtr()->getNodesBySolid(fc); - for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) - ret.append(Py::Int(*it)); - - return Py::new_reference_to(ret); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getNodesByFace(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - const TopoDS_Face& fc = TopoDS::Face(sh); - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); - return 0; - } - Py::List ret; - std::set resultSet = getFemMeshPtr()->getNodesByFace(fc); - for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) - ret.append(Py::Int(*it)); - - return Py::new_reference_to(ret); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getNodesByEdge(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeEdgePy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - const TopoDS_Edge& fc = TopoDS::Edge(sh); - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Edge is empty"); - return 0; - } - Py::List ret; - std::set resultSet = getFemMeshPtr()->getNodesByEdge(fc); - for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) - ret.append(Py::Int(*it)); - - return Py::new_reference_to(ret); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getNodesByVertex(PyObject *args) -{ - PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeVertexPy::Type), &pW)) - return 0; - - try { - const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - const TopoDS_Vertex& fc = TopoDS::Vertex(sh); - if (sh.IsNull()) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "Vertex is empty"); - return 0; - } - Py::List ret; - std::set resultSet = getFemMeshPtr()->getNodesByVertex(fc); - for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) - ret.append(Py::Int(*it)); - - return Py::new_reference_to(ret); - - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - -PyObject* FemMeshPy::getElementNodes(PyObject *args) -{ - int id; - if (!PyArg_ParseTuple(args, "i", &id)) - return 0; - - try { - std::list resultSet = getFemMeshPtr()->getElementNodes(id); - Py::Tuple ret(resultSet.size()); - int index = 0; - for (std::list::const_iterator it = resultSet.begin();it!=resultSet.end();++it) - ret.setItem(index++, Py::Int(*it)); - - return Py::new_reference_to(ret); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } -} - - -// ===== Atributes ============================================================ - -Py::Dict FemMeshPy::getNodes(void) const -{ - //int count = getFemMeshPtr()->getSMesh()->GetMeshDS()->NbNodes(); - //Py::Tuple tup(count); - Py::Dict dict; - - // get the actuall transform of the FemMesh - Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); - - SMDS_NodeIteratorPtr aNodeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator(); - for (int i=0;aNodeIter->more();i++) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); - // Apply the matrix to hold the BoundBox in absolute space. - vec = Mtrx * vec; - int id = aNode->GetID(); - - dict[Py::Int(id)] = Py::asObject(new Base::VectorPy( vec )); - } - - return dict; -} - -Py::Int FemMeshPy::getNodeCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbNodes()); -} - -Py::Tuple FemMeshPy::getEdges(void) const -{ - std::set ids; - SMDS_EdgeIteratorPtr aEdgeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->edgesIterator(); - while (aEdgeIter->more()) { - const SMDS_MeshEdge* aEdge = aEdgeIter->next(); - ids.insert(aEdge->GetID()); - } - - Py::Tuple tuple(ids.size()); - int index = 0; - for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { - tuple.setItem(index++, Py::Int(*it)); - } - - return tuple; -} - -Py::Int FemMeshPy::getEdgeCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbEdges()); -} - -Py::Tuple FemMeshPy::getFaces(void) const -{ - std::set ids; - SMDS_FaceIteratorPtr aFaceIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->facesIterator(); - while (aFaceIter->more()) { - const SMDS_MeshFace* aFace = aFaceIter->next(); - ids.insert(aFace->GetID()); - } - - Py::Tuple tuple(ids.size()); - int index = 0; - for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { - tuple.setItem(index++, Py::Int(*it)); - } - - return tuple; -} - -Py::Int FemMeshPy::getFaceCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbFaces()); -} - -Py::Int FemMeshPy::getTriangleCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbTriangles()); -} - -Py::Int FemMeshPy::getQuadrangleCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbQuadrangles()); -} - -Py::Int FemMeshPy::getPolygonCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbPolygons()); -} - -Py::Tuple FemMeshPy::getVolumes(void) const -{ - std::set ids; - SMDS_VolumeIteratorPtr aVolIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator(); - while (aVolIter->more()) { - const SMDS_MeshVolume* aVol = aVolIter->next(); - ids.insert(aVol->GetID()); - } - - Py::Tuple tuple(ids.size()); - int index = 0; - for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { - tuple.setItem(index++, Py::Int(*it)); - } - - return tuple; -} - -Py::Int FemMeshPy::getVolumeCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbVolumes()); -} - -Py::Int FemMeshPy::getTetraCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbTetras()); -} - -Py::Int FemMeshPy::getHexaCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbHexas()); -} - -Py::Int FemMeshPy::getPyramidCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbPyramids()); -} - -Py::Int FemMeshPy::getPrismCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbPrisms()); -} - -Py::Int FemMeshPy::getPolyhedronCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbPolyhedrons()); -} - -Py::Int FemMeshPy::getSubMeshCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbSubMesh()); -} - -Py::Int FemMeshPy::getGroupCount(void) const -{ - return Py::Int(getFemMeshPtr()->getSMesh()->NbGroup()); -} - -Py::Object FemMeshPy::getVolume(void) const -{ - return Py::Object(new Base::QuantityPy(new Base::Quantity(getFemMeshPtr()->getVolume()))); - -} -// ===== custom attributes ============================================================ - -PyObject *FemMeshPy::getCustomAttributes(const char* /*attr*/) const -{ - return 0; -} - -int FemMeshPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) -{ - return 0; -} +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2009 * + * * + * 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" +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "Mod/Fem/App/FemMesh.h" + +// inclusion of the generated files (generated out of FemMeshPy.xml) +#include "FemMeshPy.h" +#include "FemMeshPy.cpp" +#include "HypothesisPy.h" + +using namespace Fem; + +// returns a string which represents the object e.g. when printed in python +std::string FemMeshPy::representation(void) const +{ + std::stringstream str; + getFemMeshPtr()->getSMesh()->Dump(str); + return str.str(); +} + +PyObject *FemMeshPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of FemMeshPy and the Twin object + return new FemMeshPy(new FemMesh); +} + +// constructor method +int FemMeshPy::PyInit(PyObject* args, PyObject* /*kwd*/) +{ + PyObject *pcObj=0; + if (!PyArg_ParseTuple(args, "|O", &pcObj)) // convert args: Python->C + return -1; // NULL triggers exception + + try { + // if no mesh is given + if (!pcObj) return 0; + if (PyObject_TypeCheck(pcObj, &(FemMeshPy::Type))) { + getFemMeshPtr()->operator= (*static_cast(pcObj)->getFemMeshPtr()); + } + else { + PyErr_Format(PyExc_TypeError, "Cannot create a FemMesh out of a '%s'", + pcObj->ob_type->tp_name); + return -1; + } + } + catch (const Base::Exception &e) { + PyErr_SetString(Base::BaseExceptionFreeCADError,e.what()); + return -1; + } + catch (const std::exception &e) { + PyErr_SetString(Base::BaseExceptionFreeCADError,e.what()); + return -1; + } + catch (const Py::Exception&) { + return -1; + } + + return 0; +} + + +// ===== Methods ============================================================ + +PyObject* FemMeshPy::setShape(PyObject *args) +{ + PyObject *pcObj; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) + return 0; + + try { + TopoDS_Shape shape = static_cast(pcObj)->getTopoShapePtr()->_Shape; + getFemMeshPtr()->getSMesh()->ShapeToMesh(shape); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::addHypothesis(PyObject *args) +{ + PyObject* hyp; + PyObject* shp=0; + // Since we have not a common base class for the Python binding of the + // hypotheses classes we cannot pass a certain Python type + if (!PyArg_ParseTuple(args, "O|O!",&hyp, &(Part::TopoShapePy::Type), &shp)) + return 0; + + TopoDS_Shape shape; + if (shp == 0) + shape = getFemMeshPtr()->getSMesh()->GetShapeToMesh(); + else + shape = static_cast(shp)->getTopoShapePtr()->_Shape; + + try { + Py::Object obj(hyp); + Fem::Hypothesis attr(obj.getAttr("this")); + SMESH_HypothesisPtr thesis = attr.extensionObject()->getHypothesis(); + getFemMeshPtr()->addHypothesis(shape, thesis); + } + catch (const Py::Exception&) { + return 0; + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::setStanardHypotheses(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return 0; + + try { + getFemMeshPtr()->setStanardHypotheses(); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::compute(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return 0; + + try { + getFemMeshPtr()->compute(); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::addNode(PyObject *args) +{ + double x,y,z; + int i = -1; + if (PyArg_ParseTuple(args, "ddd",&x,&y,&z)){ + try { + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + SMDS_MeshNode* node = meshDS->AddNode(x,y,z); + if (!node) + throw std::runtime_error("Failed to add node"); + return Py::new_reference_to(Py::Int(node->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + } + PyErr_Clear(); + + if (PyArg_ParseTuple(args, "dddi",&x,&y,&z,&i)){ + try { + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + SMDS_MeshNode* node = meshDS->AddNodeWithID(x,y,z,i); + if (!node) + throw std::runtime_error("Failed to add node"); + return Py::new_reference_to(Py::Int(node->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + } + PyErr_SetString(PyExc_TypeError, "addNode() accepts:\n" + "-- addNode(x,y,z)\n" + "-- addNode(x,y,z,ElemId)\n"); + return 0; + +} + +PyObject* FemMeshPy::addEdge(PyObject *args) +{ + int n1,n2; + if (!PyArg_ParseTuple(args, "ii",&n1,&n2)) + return 0; + + try { + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + const SMDS_MeshNode* node1 = meshDS->FindNode(n1); + const SMDS_MeshNode* node2 = meshDS->FindNode(n2); + if (!node1 || !node2) + throw std::runtime_error("Failed to get node of the given indices"); + SMDS_MeshEdge* edge = meshDS->AddEdge(node1, node2); + if (!edge) + throw std::runtime_error("Failed to add edge"); + return Py::new_reference_to(Py::Int(edge->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } +} + +PyObject* FemMeshPy::addFace(PyObject *args) +{ + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + + int n1,n2,n3; + if (PyArg_ParseTuple(args, "iii",&n1,&n2,&n3)) + { + // old form, deprecated + try { + const SMDS_MeshNode* node1 = meshDS->FindNode(n1); + const SMDS_MeshNode* node2 = meshDS->FindNode(n2); + const SMDS_MeshNode* node3 = meshDS->FindNode(n3); + if (!node1 || !node2 || !node3) + throw std::runtime_error("Failed to get node of the given indices"); + SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3); + if (!face) + throw std::runtime_error("Failed to add face"); + return Py::new_reference_to(Py::Int(face->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + } + PyErr_Clear(); + + PyObject *obj; + int ElementId=-1; + if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) + { + Py::List list(obj); + std::vector Nodes; + for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { + Py::Int NoNr(*it); + const SMDS_MeshNode* node = meshDS->FindNode(NoNr); + if (!node) + throw std::runtime_error("Failed to get node of the given indices"); + Nodes.push_back(node); + } + + SMDS_MeshFace* face=0; + switch(Nodes.size()){ + case 3: + face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2]); + if (!face) + throw std::runtime_error("Failed to add triangular face"); + break; + case 4: + face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3]); + if (!face) + throw std::runtime_error("Failed to add face"); + break; + case 6: + face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5]); + if (!face) + throw std::runtime_error("Failed to add face"); + break; + case 8: + face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7]); + if (!face) + throw std::runtime_error("Failed to add face"); + break; + default: + throw std::runtime_error("Unknown node count, [3|4|6|8] are allowed"); //unknown face type + } + + return Py::new_reference_to(Py::Int(face->GetID())); + + } + + PyErr_SetString(PyExc_TypeError, "addFace accepts:\n" + "-- int,int,int\n" + "-- [3|4|6|8 int],[int]\n"); + return 0; +} + +PyObject* FemMeshPy::addQuad(PyObject *args) +{ + int n1,n2,n3,n4; + if (!PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4)) + return 0; + + try { + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + const SMDS_MeshNode* node1 = meshDS->FindNode(n1); + const SMDS_MeshNode* node2 = meshDS->FindNode(n2); + const SMDS_MeshNode* node3 = meshDS->FindNode(n3); + const SMDS_MeshNode* node4 = meshDS->FindNode(n4); + if (!node1 || !node2 || !node3 || !node4) + throw std::runtime_error("Failed to get node of the given indices"); + SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3, node4); + if (!face) + throw std::runtime_error("Failed to add quad"); + return Py::new_reference_to(Py::Int(face->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } +} + +PyObject* FemMeshPy::addVolume(PyObject *args) +{ + SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); + SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); + + int n1,n2,n3,n4; + if (PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4)) + { + try { + const SMDS_MeshNode* node1 = meshDS->FindNode(n1); + const SMDS_MeshNode* node2 = meshDS->FindNode(n2); + const SMDS_MeshNode* node3 = meshDS->FindNode(n3); + const SMDS_MeshNode* node4 = meshDS->FindNode(n4); + if (!node1 || !node2 || !node3 || !node4) + throw std::runtime_error("Failed to get node of the given indices"); + SMDS_MeshVolume* vol = meshDS->AddVolume(node1, node2, node3, node4); + if (!vol) + throw std::runtime_error("Failed to add volume"); + return Py::new_reference_to(Py::Int(vol->GetID())); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + } + PyErr_Clear(); + + PyObject *obj; + int ElementId=-1; + if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) + { + Py::List list(obj); + std::vector Nodes; + for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { + Py::Int NoNr(*it); + const SMDS_MeshNode* node = meshDS->FindNode(NoNr); + if (!node) + throw std::runtime_error("Failed to get node of the given indices"); + Nodes.push_back(node); + } + + SMDS_MeshVolume* vol=0; + if(ElementId != -1) { + switch(Nodes.size()){ + case 4: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Tet4 volume"); + break; + case 5: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Pyra5 volume"); + break; + case 6: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Penta6 volume"); + break; + case 8: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Hexa8 volume"); + break; + case 10: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Tet10 volume"); + break; + case 13: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Pyra13 volume"); + case 15: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Penta15 volume"); + case 20: + vol = meshDS->AddVolumeWithID(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],Nodes[15],Nodes[16],Nodes[17],Nodes[18],Nodes[19],ElementId); + if (!vol) + throw std::runtime_error("Failed to add Hexa20 volume"); + break; + + default: throw std::runtime_error("Unknown node count, [4|5|6|8|10|13|15|20] are allowed"); //unknown volume type + } + }else{ + switch(Nodes.size()){ + case 4: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3]); + if (!vol) + throw std::runtime_error("Failed to add Tet4 volume"); + break; + case 5: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4]); + if (!vol) + throw std::runtime_error("Failed to add Pyra5 volume"); + break; + case 6: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5]); + if (!vol) + throw std::runtime_error("Failed to add Penta6 volume"); + break; + case 8: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7]); + if (!vol) + throw std::runtime_error("Failed to add Hexa8 volume"); + break; + case 10: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9]); + if (!vol) + throw std::runtime_error("Failed to add Tet10 volume"); + break; + case 13: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12]); + if (!vol) + throw std::runtime_error("Failed to add Pyra13 volume"); + break; + case 15: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14]); + if (!vol) + throw std::runtime_error("Failed to add Penta15 volume"); + break; + case 20: + vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9],Nodes[10],Nodes[11],Nodes[12],Nodes[13],Nodes[14],Nodes[15],Nodes[16],Nodes[17],Nodes[18],Nodes[19]); + if (!vol) + throw std::runtime_error("Failed to add Hexa20 volume"); + break; + + default: throw std::runtime_error("Unknown node count, [4|5|6|8|10|13|15|20] are allowed"); //unknown volume type + } + + } + + return Py::new_reference_to(Py::Int(vol->GetID())); + + } + + PyErr_SetString(PyExc_TypeError, "addVolume accepts:\n" + "-- int,int,int,int\n" + "-- [4|5|6|8|10|13|15|20 int],[int]\n"); + return 0; + +} + +PyObject* FemMeshPy::copy(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return 0; + + const FemMesh& mesh = *getFemMeshPtr(); + return new FemMeshPy(new FemMesh(mesh)); +} + +PyObject* FemMeshPy::read(PyObject *args) +{ + char* Name; + if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) + return 0; + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + try { + getFemMeshPtr()->read(EncodedName.c_str()); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::write(PyObject *args) +{ + char* Name; + if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) + return 0; + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + try { + getFemMeshPtr()->write(EncodedName.c_str()); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::writeABAQUS(PyObject *args) +{ + char* Name; + if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) + return 0; + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + try { + getFemMeshPtr()->writeABAQUS(EncodedName.c_str()); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::setTransform(PyObject *args) +{ + PyObject* ptr; + if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &ptr)) + return 0; + + try { + Base::Placement* placement = static_cast(ptr)->getPlacementPtr(); + Base::Matrix4D mat = placement->toMatrix(); + getFemMeshPtr()->transformGeometry(mat); + } + catch (const std::exception& e) { + PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); + return 0; + } + Py_Return; +} + +PyObject* FemMeshPy::getVolumesByFace(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); + return 0; + } + + const TopoDS_Face& fc = TopoDS::Face(sh); + + Py::List ret; + std::list > resultSet = getFemMeshPtr()->getVolumesByFace(fc); + for (std::list >::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { + Py::Tuple vol_face(2); + vol_face.setItem(0, Py::Int(it->first)); + vol_face.setItem(1, Py::Int(it->second)); + ret.append(vol_face); + } + + return Py::new_reference_to(ret); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getccxVolumesByFace(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); + return 0; + } + + const TopoDS_Face& fc = TopoDS::Face(sh); + + Py::List ret; + std::map resultSet = getFemMeshPtr()->getccxVolumesByFace(fc); + for (std::map::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { + Py::Tuple vol_face(2); + vol_face.setItem(0, Py::Int(it->first)); + vol_face.setItem(1, Py::Int(it->second)); + ret.append(vol_face); + } + + return Py::new_reference_to(ret); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getNodeById(PyObject *args) +{ + int id; + if (!PyArg_ParseTuple(args, "i", &id)) + return 0; + + Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); + const SMDS_MeshNode* aNode = getFemMeshPtr()->getSMesh()->GetMeshDS()->FindNode(id); + + if(aNode){ + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + vec = Mtrx * vec; + return new Base::VectorPy( vec ); + }else{ + PyErr_SetString(Base::BaseExceptionFreeCADError, "No valid ID"); + return 0; + } +} + +PyObject* FemMeshPy::getNodesBySolid(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeSolidPy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Solid& fc = TopoDS::Solid(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Solid is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getNodesBySolid(fc); + for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.append(Py::Int(*it)); + + return Py::new_reference_to(ret); + + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getNodesByFace(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Face& fc = TopoDS::Face(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getNodesByFace(fc); + for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.append(Py::Int(*it)); + + return Py::new_reference_to(ret); + + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getNodesByEdge(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeEdgePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Edge& fc = TopoDS::Edge(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Edge is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getNodesByEdge(fc); + for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.append(Py::Int(*it)); + + return Py::new_reference_to(ret); + + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getNodesByVertex(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeVertexPy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Vertex& fc = TopoDS::Vertex(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Vertex is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getNodesByVertex(fc); + for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.append(Py::Int(*it)); + + return Py::new_reference_to(ret); + + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + +PyObject* FemMeshPy::getElementNodes(PyObject *args) +{ + int id; + if (!PyArg_ParseTuple(args, "i", &id)) + return 0; + + try { + std::list resultSet = getFemMeshPtr()->getElementNodes(id); + Py::Tuple ret(resultSet.size()); + int index = 0; + for (std::list::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.setItem(index++, Py::Int(*it)); + + return Py::new_reference_to(ret); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + + +// ===== Atributes ============================================================ + +Py::Dict FemMeshPy::getNodes(void) const +{ + //int count = getFemMeshPtr()->getSMesh()->GetMeshDS()->NbNodes(); + //Py::Tuple tup(count); + Py::Dict dict; + + // get the actuall transform of the FemMesh + Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); + + SMDS_NodeIteratorPtr aNodeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator(); + for (int i=0;aNodeIter->more();i++) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = Mtrx * vec; + int id = aNode->GetID(); + + dict[Py::Int(id)] = Py::asObject(new Base::VectorPy( vec )); + } + + return dict; +} + +Py::Int FemMeshPy::getNodeCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbNodes()); +} + +Py::Tuple FemMeshPy::getEdges(void) const +{ + std::set ids; + SMDS_EdgeIteratorPtr aEdgeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->edgesIterator(); + while (aEdgeIter->more()) { + const SMDS_MeshEdge* aEdge = aEdgeIter->next(); + ids.insert(aEdge->GetID()); + } + + Py::Tuple tuple(ids.size()); + int index = 0; + for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { + tuple.setItem(index++, Py::Int(*it)); + } + + return tuple; +} + +Py::Int FemMeshPy::getEdgeCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbEdges()); +} + +Py::Tuple FemMeshPy::getFaces(void) const +{ + std::set ids; + SMDS_FaceIteratorPtr aFaceIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->facesIterator(); + while (aFaceIter->more()) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + ids.insert(aFace->GetID()); + } + + Py::Tuple tuple(ids.size()); + int index = 0; + for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { + tuple.setItem(index++, Py::Int(*it)); + } + + return tuple; +} + +Py::Int FemMeshPy::getFaceCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbFaces()); +} + +Py::Int FemMeshPy::getTriangleCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbTriangles()); +} + +Py::Int FemMeshPy::getQuadrangleCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbQuadrangles()); +} + +Py::Int FemMeshPy::getPolygonCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbPolygons()); +} + +Py::Tuple FemMeshPy::getVolumes(void) const +{ + std::set ids; + SMDS_VolumeIteratorPtr aVolIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator(); + while (aVolIter->more()) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + ids.insert(aVol->GetID()); + } + + Py::Tuple tuple(ids.size()); + int index = 0; + for (std::set::iterator it = ids.begin(); it != ids.end(); ++it) { + tuple.setItem(index++, Py::Int(*it)); + } + + return tuple; +} + +Py::Int FemMeshPy::getVolumeCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbVolumes()); +} + +Py::Int FemMeshPy::getTetraCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbTetras()); +} + +Py::Int FemMeshPy::getHexaCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbHexas()); +} + +Py::Int FemMeshPy::getPyramidCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbPyramids()); +} + +Py::Int FemMeshPy::getPrismCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbPrisms()); +} + +Py::Int FemMeshPy::getPolyhedronCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbPolyhedrons()); +} + +Py::Int FemMeshPy::getSubMeshCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbSubMesh()); +} + +Py::Int FemMeshPy::getGroupCount(void) const +{ + return Py::Int(getFemMeshPtr()->getSMesh()->NbGroup()); +} + +Py::Object FemMeshPy::getVolume(void) const +{ + return Py::Object(new Base::QuantityPy(new Base::Quantity(getFemMeshPtr()->getVolume()))); + +} +// ===== custom attributes ============================================================ + +PyObject *FemMeshPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int FemMeshPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} diff --git a/src/Mod/Fem/App/HypothesisPy.h b/src/Mod/Fem/App/HypothesisPy.h index 776c80c8ca29..8c1cde7e94a7 100755 --- a/src/Mod/Fem/App/HypothesisPy.h +++ b/src/Mod/Fem/App/HypothesisPy.h @@ -1,423 +1,423 @@ -/*************************************************************************** - * Copyright (c) 2010 Werner Mayer * - * * - * 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 * - * * - ***************************************************************************/ - -#ifndef FEM_HYPOTHESISPY_H -#define FEM_HYPOTHESISPY_H - -#include -#include - -class SMESH_Hypothesis; -class SMESH_Gen; - -namespace Fem { - -class HypothesisPy : public Py::PythonExtension -{ -public: - typedef Py::PythonExtension HypothesisPyBase; - HypothesisPy(boost::shared_ptr); - virtual ~HypothesisPy(); - boost::shared_ptr getHypothesis() const - { return hyp; } - -private: - boost::shared_ptr hyp; -}; - -typedef Py::ExtensionObject Hypothesis; - -template -class SMESH_HypothesisPy : public Py::PythonExtension -{ -public: - typedef SMESH_HypothesisPy SMESH_HypothesisPyBase; - static void init_type(PyObject*); // announce properties and methods - - SMESH_HypothesisPy(SMESH_Hypothesis*); - virtual ~SMESH_HypothesisPy(); - - Py::Object getattr(const char *name); - Py::Object repr(); - Py::Object getLibName(const Py::Tuple& args); - Py::Object setLibName(const Py::Tuple& args); - Py::Object setParameters(const Py::Tuple& args); - Py::Object getParameters(const Py::Tuple& args); - Py::Object setLastParameters(const Py::Tuple& args); - Py::Object getLastParameters(const Py::Tuple& args); - Py::Object clearParameters(const Py::Tuple& args); +/*************************************************************************** + * Copyright (c) 2010 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef FEM_HYPOTHESISPY_H +#define FEM_HYPOTHESISPY_H + +#include +#include + +class SMESH_Hypothesis; +class SMESH_Gen; + +namespace Fem { + +class HypothesisPy : public Py::PythonExtension +{ +public: + typedef Py::PythonExtension HypothesisPyBase; + HypothesisPy(boost::shared_ptr); + virtual ~HypothesisPy(); + boost::shared_ptr getHypothesis() const + { return hyp; } + +private: + boost::shared_ptr hyp; +}; + +typedef Py::ExtensionObject Hypothesis; + +template +class SMESH_HypothesisPy : public Py::PythonExtension +{ +public: + typedef SMESH_HypothesisPy SMESH_HypothesisPyBase; + static void init_type(PyObject*); // announce properties and methods + + SMESH_HypothesisPy(SMESH_Hypothesis*); + virtual ~SMESH_HypothesisPy(); + + Py::Object getattr(const char *name); + Py::Object repr(); + Py::Object getLibName(const Py::Tuple& args); + Py::Object setLibName(const Py::Tuple& args); + Py::Object setParameters(const Py::Tuple& args); + Py::Object getParameters(const Py::Tuple& args); + Py::Object setLastParameters(const Py::Tuple& args); + Py::Object getLastParameters(const Py::Tuple& args); + Py::Object clearParameters(const Py::Tuple& args); Py::Object isAuxiliary(const Py::Tuple& args); Py::Object setParametersByMesh(const Py::Tuple& args); - - boost::shared_ptr getHypothesis() const - { return hyp; } - -protected: - template - type* hypothesis() const - { return static_cast(hyp.get()); } - -private: - static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *); - -private: - boost::shared_ptr hyp; -}; - -class StdMeshers_Arithmetic1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Arithmetic1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Arithmetic1DPy(); - - Py::Object setLength(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); -}; - -class StdMeshers_AutomaticLengthPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_AutomaticLengthPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_AutomaticLengthPy(); - - Py::Object setFineness(const Py::Tuple& args); - Py::Object getFineness(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); -}; - -class StdMeshers_NotConformAllowedPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_NotConformAllowedPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_NotConformAllowedPy(); -}; - -class StdMeshers_MaxLengthPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_MaxLengthPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_MaxLengthPy(); - - Py::Object setLength(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); - Py::Object havePreestimatedLength(const Py::Tuple& args); - Py::Object getPreestimatedLength(const Py::Tuple& args); - Py::Object setPreestimatedLength(const Py::Tuple& args); - Py::Object setUsePreestimatedLength(const Py::Tuple& args); - Py::Object getUsePreestimatedLength(const Py::Tuple& args); -}; - -class StdMeshers_LocalLengthPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_LocalLengthPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_LocalLengthPy(); - - Py::Object setLength(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); - Py::Object setPrecision(const Py::Tuple& args); - Py::Object getPrecision(const Py::Tuple& args); -}; - -class StdMeshers_MaxElementAreaPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_MaxElementAreaPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_MaxElementAreaPy(); - - Py::Object setMaxArea(const Py::Tuple& args); - Py::Object getMaxArea(const Py::Tuple& args); -}; - -class StdMeshers_QuadranglePreferencePy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_QuadranglePreferencePy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_QuadranglePreferencePy(); -}; - -class StdMeshers_Quadrangle_2DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Quadrangle_2DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Quadrangle_2DPy(); -}; - -class StdMeshers_Regular_1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Regular_1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Regular_1DPy(); -}; - -class StdMeshers_UseExisting_1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_UseExisting_1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_UseExisting_1DPy(); -}; - -class StdMeshers_UseExisting_2DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_UseExisting_2DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_UseExisting_2DPy(); -}; - -class StdMeshers_CompositeSegment_1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_CompositeSegment_1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_CompositeSegment_1DPy(); -}; - -class StdMeshers_Deflection1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Deflection1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Deflection1DPy(); - - Py::Object setDeflection(const Py::Tuple& args); -}; - -class StdMeshers_Hexa_3DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Hexa_3DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Hexa_3DPy(); -}; - -class StdMeshers_TrianglePreferencePy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_TrianglePreferencePy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_TrianglePreferencePy(); -}; - -class StdMeshers_StartEndLengthPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_StartEndLengthPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_StartEndLengthPy(); - Py::Object setLength(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); -}; - -class StdMeshers_SegmentLengthAroundVertexPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_SegmentLengthAroundVertexPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_SegmentLengthAroundVertexPy(); - Py::Object setLength(const Py::Tuple& args); - Py::Object getLength(const Py::Tuple& args); -}; - -class StdMeshers_SegmentAroundVertex_0DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_SegmentAroundVertex_0DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_SegmentAroundVertex_0DPy(); -}; - -class StdMeshers_RadialPrism_3DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_RadialPrism_3DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_RadialPrism_3DPy(); -}; - -class StdMeshers_QuadraticMeshPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_QuadraticMeshPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_QuadraticMeshPy(); -}; - -class StdMeshers_ProjectionSource3DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_ProjectionSource3DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_ProjectionSource3DPy(); - //Py::Object setSource3DShape(const Py::Tuple& args); - //Py::Object getSource3DShape(const Py::Tuple& args); - //Py::Object setSourceMesh(const Py::Tuple& args); - //Py::Object getSourceMesh(const Py::Tuple& args); - //Py::Object setVertexAssociation(const Py::Tuple& args); - //Py::Object getSourceVertex(const Py::Tuple& args); - //Py::Object getTargetVertex(const Py::Tuple& args); - //Py::Object hasVertexAssociation(const Py::Tuple& args); - //Py::Object getStoreParams(const Py::Tuple& args); - //Py::Object restoreParams(const Py::Tuple& args); -}; - -class StdMeshers_ProjectionSource2DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_ProjectionSource2DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_ProjectionSource2DPy(); - //Py::Object setSourceFace(const Py::Tuple& args); - //Py::Object getSourceFace(const Py::Tuple& args); - //Py::Object isCompoundSource(const Py::Tuple& args); - //Py::Object setSourceMesh(const Py::Tuple& args); - //Py::Object getSourceMesh(const Py::Tuple& args); - //Py::Object setVertexAssociation(const Py::Tuple& args); - //Py::Object getSourceVertex(const Py::Tuple& args); - //Py::Object getTargetVertex(const Py::Tuple& args); - //Py::Object hasVertexAssociation(const Py::Tuple& args); - //Py::Object getStoreParams(const Py::Tuple& args); - //Py::Object restoreParams(const Py::Tuple& args); -}; - -class StdMeshers_ProjectionSource1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_ProjectionSource1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_ProjectionSource1DPy(); - //Py::Object setSourceEdge(const Py::Tuple& args); - //Py::Object getSourceEdge(const Py::Tuple& args); - //Py::Object isCompoundSource(const Py::Tuple& args); - //Py::Object setSourceMesh(const Py::Tuple& args); - //Py::Object getSourceMesh(const Py::Tuple& args); - //Py::Object setVertexAssociation(const Py::Tuple& args); - //Py::Object getSourceVertex(const Py::Tuple& args); - //Py::Object getTargetVertex(const Py::Tuple& args); - //Py::Object hasVertexAssociation(const Py::Tuple& args); - //Py::Object getStoreParams(const Py::Tuple& args); - //Py::Object restoreParams(const Py::Tuple& args); -}; - -class StdMeshers_Projection_3DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Projection_3DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Projection_3DPy(); -}; - -class StdMeshers_Projection_2DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Projection_2DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Projection_2DPy(); -}; - -class StdMeshers_Projection_1DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Projection_1DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Projection_1DPy(); -}; - -class StdMeshers_Prism_3DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_Prism_3DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_Prism_3DPy(); -}; - -class StdMeshers_NumberOfSegmentsPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_NumberOfSegmentsPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_NumberOfSegmentsPy(); - Py::Object setNumSegm(const Py::Tuple& args); - Py::Object getNumSegm(const Py::Tuple& args); -}; - -class StdMeshers_NumberOfLayersPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_NumberOfLayersPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_NumberOfLayersPy(); - Py::Object setNumLayers(const Py::Tuple& args); - Py::Object getNumLayers(const Py::Tuple& args); -}; - -class StdMeshers_MEFISTO_2DPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_MEFISTO_2DPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_MEFISTO_2DPy(); -}; - -class StdMeshers_MaxElementVolumePy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_MaxElementVolumePy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_MaxElementVolumePy(); - Py::Object setMaxVolume(const Py::Tuple& args); - Py::Object getMaxVolume(const Py::Tuple& args); -}; - -class StdMeshers_LengthFromEdgesPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_LengthFromEdgesPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_LengthFromEdgesPy(); - Py::Object setMode(const Py::Tuple& args); - Py::Object getMode(const Py::Tuple& args); -}; - -class StdMeshers_LayerDistributionPy : public SMESH_HypothesisPy -{ -public: - static void init_type(PyObject*); - StdMeshers_LayerDistributionPy(int hypId, int studyId, SMESH_Gen* gen); - ~StdMeshers_LayerDistributionPy(); - Py::Object setLayerDistribution(const Py::Tuple& args); - Py::Object getLayerDistribution(const Py::Tuple& args); -}; - -} // namespace Fem - -#endif // FEM_HYPOTHESISPY_H + + boost::shared_ptr getHypothesis() const + { return hyp; } + +protected: + template + type* hypothesis() const + { return static_cast(hyp.get()); } + +private: + static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *); + +private: + boost::shared_ptr hyp; +}; + +class StdMeshers_Arithmetic1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Arithmetic1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Arithmetic1DPy(); + + Py::Object setLength(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); +}; + +class StdMeshers_AutomaticLengthPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_AutomaticLengthPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_AutomaticLengthPy(); + + Py::Object setFineness(const Py::Tuple& args); + Py::Object getFineness(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); +}; + +class StdMeshers_NotConformAllowedPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_NotConformAllowedPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_NotConformAllowedPy(); +}; + +class StdMeshers_MaxLengthPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_MaxLengthPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_MaxLengthPy(); + + Py::Object setLength(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); + Py::Object havePreestimatedLength(const Py::Tuple& args); + Py::Object getPreestimatedLength(const Py::Tuple& args); + Py::Object setPreestimatedLength(const Py::Tuple& args); + Py::Object setUsePreestimatedLength(const Py::Tuple& args); + Py::Object getUsePreestimatedLength(const Py::Tuple& args); +}; + +class StdMeshers_LocalLengthPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_LocalLengthPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_LocalLengthPy(); + + Py::Object setLength(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); + Py::Object setPrecision(const Py::Tuple& args); + Py::Object getPrecision(const Py::Tuple& args); +}; + +class StdMeshers_MaxElementAreaPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_MaxElementAreaPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_MaxElementAreaPy(); + + Py::Object setMaxArea(const Py::Tuple& args); + Py::Object getMaxArea(const Py::Tuple& args); +}; + +class StdMeshers_QuadranglePreferencePy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_QuadranglePreferencePy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_QuadranglePreferencePy(); +}; + +class StdMeshers_Quadrangle_2DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Quadrangle_2DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Quadrangle_2DPy(); +}; + +class StdMeshers_Regular_1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Regular_1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Regular_1DPy(); +}; + +class StdMeshers_UseExisting_1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_UseExisting_1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_UseExisting_1DPy(); +}; + +class StdMeshers_UseExisting_2DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_UseExisting_2DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_UseExisting_2DPy(); +}; + +class StdMeshers_CompositeSegment_1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_CompositeSegment_1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_CompositeSegment_1DPy(); +}; + +class StdMeshers_Deflection1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Deflection1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Deflection1DPy(); + + Py::Object setDeflection(const Py::Tuple& args); +}; + +class StdMeshers_Hexa_3DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Hexa_3DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Hexa_3DPy(); +}; + +class StdMeshers_TrianglePreferencePy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_TrianglePreferencePy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_TrianglePreferencePy(); +}; + +class StdMeshers_StartEndLengthPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_StartEndLengthPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_StartEndLengthPy(); + Py::Object setLength(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); +}; + +class StdMeshers_SegmentLengthAroundVertexPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_SegmentLengthAroundVertexPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_SegmentLengthAroundVertexPy(); + Py::Object setLength(const Py::Tuple& args); + Py::Object getLength(const Py::Tuple& args); +}; + +class StdMeshers_SegmentAroundVertex_0DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_SegmentAroundVertex_0DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_SegmentAroundVertex_0DPy(); +}; + +class StdMeshers_RadialPrism_3DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_RadialPrism_3DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_RadialPrism_3DPy(); +}; + +class StdMeshers_QuadraticMeshPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_QuadraticMeshPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_QuadraticMeshPy(); +}; + +class StdMeshers_ProjectionSource3DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_ProjectionSource3DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_ProjectionSource3DPy(); + //Py::Object setSource3DShape(const Py::Tuple& args); + //Py::Object getSource3DShape(const Py::Tuple& args); + //Py::Object setSourceMesh(const Py::Tuple& args); + //Py::Object getSourceMesh(const Py::Tuple& args); + //Py::Object setVertexAssociation(const Py::Tuple& args); + //Py::Object getSourceVertex(const Py::Tuple& args); + //Py::Object getTargetVertex(const Py::Tuple& args); + //Py::Object hasVertexAssociation(const Py::Tuple& args); + //Py::Object getStoreParams(const Py::Tuple& args); + //Py::Object restoreParams(const Py::Tuple& args); +}; + +class StdMeshers_ProjectionSource2DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_ProjectionSource2DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_ProjectionSource2DPy(); + //Py::Object setSourceFace(const Py::Tuple& args); + //Py::Object getSourceFace(const Py::Tuple& args); + //Py::Object isCompoundSource(const Py::Tuple& args); + //Py::Object setSourceMesh(const Py::Tuple& args); + //Py::Object getSourceMesh(const Py::Tuple& args); + //Py::Object setVertexAssociation(const Py::Tuple& args); + //Py::Object getSourceVertex(const Py::Tuple& args); + //Py::Object getTargetVertex(const Py::Tuple& args); + //Py::Object hasVertexAssociation(const Py::Tuple& args); + //Py::Object getStoreParams(const Py::Tuple& args); + //Py::Object restoreParams(const Py::Tuple& args); +}; + +class StdMeshers_ProjectionSource1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_ProjectionSource1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_ProjectionSource1DPy(); + //Py::Object setSourceEdge(const Py::Tuple& args); + //Py::Object getSourceEdge(const Py::Tuple& args); + //Py::Object isCompoundSource(const Py::Tuple& args); + //Py::Object setSourceMesh(const Py::Tuple& args); + //Py::Object getSourceMesh(const Py::Tuple& args); + //Py::Object setVertexAssociation(const Py::Tuple& args); + //Py::Object getSourceVertex(const Py::Tuple& args); + //Py::Object getTargetVertex(const Py::Tuple& args); + //Py::Object hasVertexAssociation(const Py::Tuple& args); + //Py::Object getStoreParams(const Py::Tuple& args); + //Py::Object restoreParams(const Py::Tuple& args); +}; + +class StdMeshers_Projection_3DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Projection_3DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Projection_3DPy(); +}; + +class StdMeshers_Projection_2DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Projection_2DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Projection_2DPy(); +}; + +class StdMeshers_Projection_1DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Projection_1DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Projection_1DPy(); +}; + +class StdMeshers_Prism_3DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_Prism_3DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_Prism_3DPy(); +}; + +class StdMeshers_NumberOfSegmentsPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_NumberOfSegmentsPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_NumberOfSegmentsPy(); + Py::Object setNumSegm(const Py::Tuple& args); + Py::Object getNumSegm(const Py::Tuple& args); +}; + +class StdMeshers_NumberOfLayersPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_NumberOfLayersPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_NumberOfLayersPy(); + Py::Object setNumLayers(const Py::Tuple& args); + Py::Object getNumLayers(const Py::Tuple& args); +}; + +class StdMeshers_MEFISTO_2DPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_MEFISTO_2DPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_MEFISTO_2DPy(); +}; + +class StdMeshers_MaxElementVolumePy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_MaxElementVolumePy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_MaxElementVolumePy(); + Py::Object setMaxVolume(const Py::Tuple& args); + Py::Object getMaxVolume(const Py::Tuple& args); +}; + +class StdMeshers_LengthFromEdgesPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_LengthFromEdgesPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_LengthFromEdgesPy(); + Py::Object setMode(const Py::Tuple& args); + Py::Object getMode(const Py::Tuple& args); +}; + +class StdMeshers_LayerDistributionPy : public SMESH_HypothesisPy +{ +public: + static void init_type(PyObject*); + StdMeshers_LayerDistributionPy(int hypId, int studyId, SMESH_Gen* gen); + ~StdMeshers_LayerDistributionPy(); + Py::Object setLayerDistribution(const Py::Tuple& args); + Py::Object getLayerDistribution(const Py::Tuple& args); +}; + +} // namespace Fem + +#endif // FEM_HYPOTHESISPY_H diff --git a/src/Mod/Fem/App/PreCompiled.cpp b/src/Mod/Fem/App/PreCompiled.cpp index 46269e9671fe..12e9b02f9747 100644 --- a/src/Mod/Fem/App/PreCompiled.cpp +++ b/src/Mod/Fem/App/PreCompiled.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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" +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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" diff --git a/src/Mod/Fem/App/PreCompiled.h b/src/Mod/Fem/App/PreCompiled.h index b9d2684a0ab6..e433d019ee7a 100644 --- a/src/Mod/Fem/App/PreCompiled.h +++ b/src/Mod/Fem/App/PreCompiled.h @@ -1,71 +1,71 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_PRECOMPILED_H -#define FEM_PRECOMPILED_H - -#include - -// Exporting of App classes -#ifdef FC_OS_WIN32 -# define AppFemExport __declspec(dllexport) -# define FemExport __declspec(dllexport) -# define PartExport __declspec(dllimport) -# define MeshExport __declspec(dllimport) -# define BaseExport __declspec(dllimport) -#else // for Linux -# define AppFemExport -# define FemExport -# define PartExport -# define MeshExport -# define BaseExport -#endif - -#ifdef _MSC_VER -# pragma warning(disable : 4290) -# pragma warning(disable : 4275) -#endif - -#ifdef _PreComp_ - -// standard -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - - - -#endif // _PreComp_ -#endif - +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_PRECOMPILED_H +#define FEM_PRECOMPILED_H + +#include + +// Exporting of App classes +#ifdef FC_OS_WIN32 +# define AppFemExport __declspec(dllexport) +# define FemExport __declspec(dllexport) +# define PartExport __declspec(dllimport) +# define MeshExport __declspec(dllimport) +# define BaseExport __declspec(dllimport) +#else // for Linux +# define AppFemExport +# define FemExport +# define PartExport +# define MeshExport +# define BaseExport +#endif + +#ifdef _MSC_VER +# pragma warning(disable : 4290) +# pragma warning(disable : 4275) +#endif + +#ifdef _PreComp_ + +// standard +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + + + +#endif // _PreComp_ +#endif + diff --git a/src/Mod/Fem/Gui/AppFemGuiPy.cpp b/src/Mod/Fem/Gui/AppFemGuiPy.cpp index 4d149712776c..67af5424b4bc 100755 --- a/src/Mod/Fem/Gui/AppFemGuiPy.cpp +++ b/src/Mod/Fem/Gui/AppFemGuiPy.cpp @@ -1,157 +1,157 @@ -/*************************************************************************** - * Copyright (c) 2008 Werner Mayer * - * * - * 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 -# include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ActiveAnalysisObserver.h" -#include "AbaqusHighlighter.h" - - -namespace FemGui { -class Module : public Py::ExtensionModule -{ -public: - Module() : Py::ExtensionModule("FemGui") - { - add_varargs_method("setActiveAnalysis",&Module::setActiveAnalysis, - "setActiveAnalysis(AnalysisObject) -- Set the Analysis object in work." - ); - add_varargs_method("getActiveAnalysis",&Module::getActiveAnalysis, - "getActiveAnalysis() -- Returns the Analysis object in work." - ); - add_varargs_method("open",&Module::open, - "open(string) -- Opens an Abaqus file in a text editor." - ); - add_varargs_method("insert",&Module::open, - "insert(string,string) -- Opens an Abaqus file in a text editor." - ); - initialize("This module is the FemGui module."); // register with Python - } - - virtual ~Module() {} - -private: - virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) - { - try { - return Py::ExtensionModule::invoke_method_varargs(method_def, args); - } - catch (const Base::Exception &e) { - throw Py::RuntimeError(e.what()); - } - catch (const std::exception &e) { - throw Py::RuntimeError(e.what()); - } - } - Py::Object setActiveAnalysis(const Py::Tuple& args) - { - if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) { - FemGui::ActiveAnalysisObserver::instance()->highlightActiveObject(Gui::Blue,false); - FemGui::ActiveAnalysisObserver::instance()->setActiveObject(0); - } - - PyObject *object=0; - if (PyArg_ParseTuple(args.ptr(),"|O!",&(App::DocumentObjectPy::Type), &object)&& object) { - App::DocumentObject* obj = static_cast(object)->getDocumentObjectPtr(); - if (!obj || !obj->getTypeId().isDerivedFrom(Fem::FemAnalysis::getClassTypeId())){ - throw Py::Exception(Base::BaseExceptionFreeCADError, "Active Analysis object have to be of type Fem::FemAnalysis!"); - } - - // get the gui document of the Analysis Item - FemGui::ActiveAnalysisObserver::instance()->setActiveObject(static_cast(obj)); - FemGui::ActiveAnalysisObserver::instance()->highlightActiveObject(Gui::Blue,true); - } - - return Py::None(); - } - Py::Object getActiveAnalysis(const Py::Tuple& args) - { - if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) { - return Py::asObject(FemGui::ActiveAnalysisObserver::instance()->getActiveObject()->getPyObject()); - } - return Py::None(); - } - Py::Object open(const Py::Tuple& args) - { - char* Name; - const char* DocName; - if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) - throw Py::Exception(); - - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - QString fileName = QString::fromUtf8(EncodedName.c_str()); - QFileInfo fi; - fi.setFile(fileName); - QString ext = fi.completeSuffix().toLower(); - QList views = Gui::getMainWindow()->findChildren(); - for (QList::Iterator it = views.begin(); it != views.end(); ++it) { - if ((*it)->fileName() == fileName) { - (*it)->setFocus(); - return Py::None(); - } - } - - if (ext == QLatin1String("inp")) { - Gui::TextEditor* editor = new Gui::TextEditor(); +/*************************************************************************** + * Copyright (c) 2008 Werner Mayer * + * * + * 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 +# include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ActiveAnalysisObserver.h" +#include "AbaqusHighlighter.h" + + +namespace FemGui { +class Module : public Py::ExtensionModule +{ +public: + Module() : Py::ExtensionModule("FemGui") + { + add_varargs_method("setActiveAnalysis",&Module::setActiveAnalysis, + "setActiveAnalysis(AnalysisObject) -- Set the Analysis object in work." + ); + add_varargs_method("getActiveAnalysis",&Module::getActiveAnalysis, + "getActiveAnalysis() -- Returns the Analysis object in work." + ); + add_varargs_method("open",&Module::open, + "open(string) -- Opens an Abaqus file in a text editor." + ); + add_varargs_method("insert",&Module::open, + "insert(string,string) -- Opens an Abaqus file in a text editor." + ); + initialize("This module is the FemGui module."); // register with Python + } + + virtual ~Module() {} + +private: + virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args) + { + try { + return Py::ExtensionModule::invoke_method_varargs(method_def, args); + } + catch (const Base::Exception &e) { + throw Py::RuntimeError(e.what()); + } + catch (const std::exception &e) { + throw Py::RuntimeError(e.what()); + } + } + Py::Object setActiveAnalysis(const Py::Tuple& args) + { + if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) { + FemGui::ActiveAnalysisObserver::instance()->highlightActiveObject(Gui::Blue,false); + FemGui::ActiveAnalysisObserver::instance()->setActiveObject(0); + } + + PyObject *object=0; + if (PyArg_ParseTuple(args.ptr(),"|O!",&(App::DocumentObjectPy::Type), &object)&& object) { + App::DocumentObject* obj = static_cast(object)->getDocumentObjectPtr(); + if (!obj || !obj->getTypeId().isDerivedFrom(Fem::FemAnalysis::getClassTypeId())){ + throw Py::Exception(Base::BaseExceptionFreeCADError, "Active Analysis object have to be of type Fem::FemAnalysis!"); + } + + // get the gui document of the Analysis Item + FemGui::ActiveAnalysisObserver::instance()->setActiveObject(static_cast(obj)); + FemGui::ActiveAnalysisObserver::instance()->highlightActiveObject(Gui::Blue,true); + } + + return Py::None(); + } + Py::Object getActiveAnalysis(const Py::Tuple& args) + { + if (FemGui::ActiveAnalysisObserver::instance()->hasActiveObject()) { + return Py::asObject(FemGui::ActiveAnalysisObserver::instance()->getActiveObject()->getPyObject()); + } + return Py::None(); + } + Py::Object open(const Py::Tuple& args) + { + char* Name; + const char* DocName; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + QString fileName = QString::fromUtf8(EncodedName.c_str()); + QFileInfo fi; + fi.setFile(fileName); + QString ext = fi.completeSuffix().toLower(); + QList views = Gui::getMainWindow()->findChildren(); + for (QList::Iterator it = views.begin(); it != views.end(); ++it) { + if ((*it)->fileName() == fileName) { + (*it)->setFocus(); + return Py::None(); + } + } + + if (ext == QLatin1String("inp")) { + Gui::TextEditor* editor = new Gui::TextEditor(); editor->setWindowIcon(Gui::BitmapFactory().pixmap(":/icons/fem-inp-editor.svg")); - Gui::EditorView* edit = new Gui::EditorView(editor, Gui::getMainWindow()); - editor->setSyntaxHighlighter(new FemGui::AbaqusHighlighter(editor)); - edit->setDisplayName(Gui::EditorView::FileName); - edit->open(fileName); - edit->resize(400, 300); - Gui::getMainWindow()->addWindow(edit); - - QFont font = editor->font(); - font.setFamily(QString::fromLatin1("Arial")); - editor->setFont(font); - } - - return Py::None(); - } -}; - -PyObject* initModule() -{ - return (new Module)->module().ptr(); -} - -} // namespace FemGui + Gui::EditorView* edit = new Gui::EditorView(editor, Gui::getMainWindow()); + editor->setSyntaxHighlighter(new FemGui::AbaqusHighlighter(editor)); + edit->setDisplayName(Gui::EditorView::FileName); + edit->open(fileName); + edit->resize(400, 300); + Gui::getMainWindow()->addWindow(edit); + + QFont font = editor->font(); + font.setFamily(QString::fromLatin1("Arial")); + editor->setFont(font); + } + + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); +} + +} // namespace FemGui diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 79d3a4e9ec82..e0378fde834e 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -1,778 +1,778 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 -# include -# include -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ActiveAnalysisObserver.h" - -using namespace std; - - -bool getConstraintPrerequisits(Fem::FemAnalysis **Analysis) -{ - Fem::FemAnalysis* ActiveAnalysis = FemGui::ActiveAnalysisObserver::instance()->getActiveObject(); - if (!ActiveAnalysis || !ActiveAnalysis->getTypeId().isDerivedFrom(Fem::FemAnalysis::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Analysis"), - QObject::tr("You need to create or activate a Analysis")); - return true; - } - - *Analysis = static_cast(ActiveAnalysis); - - // return with no error - return false; - -} - -//OvG: Visibility automation show parts and hide meshes on activation of a constraint -std::string gethideMeshShowPartStr(std::string showConstr="") -{ - return "for amesh in App.activeDocument().Objects:\n\ - if \""+showConstr+"\" == amesh.Name:\n\ - amesh.ViewObject.Visibility = True\n\ - elif \"Mesh\" in amesh.TypeId:\n\ - aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ - for apart in App.activeDocument().Objects:\n\ - if aparttoshow == apart.Name:\n\ - apart.ViewObject.Visibility = True\n\ - amesh.ViewObject.Visibility = False\n"; -} - -//===================================================================================== -DEF_STD_CMD_A(CmdFemCreateAnalysis); - -CmdFemCreateAnalysis::CmdFemCreateAnalysis() - : Command("Fem_CreateAnalysis") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create a FEM analysis"); - sToolTipText = QT_TR_NOOP("Create a FEM analysis"); - sWhatsThis = "Fem_CreateAnalysis"; - sStatusTip = sToolTipText; - sPixmap = "fem-analysis"; -} - -void CmdFemCreateAnalysis::activated(int iMsg) -{ -#ifndef FCWithNetgen - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); - return; -#endif - - std::vector selection = getSelection().getSelectionEx(); - - if (selection.size() != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body. Only one body is allowed.")); - return; - } - - if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("Fillet works only on parts")); - return; - } - - Part::Feature *base = static_cast(selection[0].getObject()); - - std::string AnalysisName = getUniqueObjectName("FemAnalysis"); - - std::string MeshName = getUniqueObjectName((std::string(base->getNameInDocument()) +"_Mesh").c_str()); - - - openCommand("Create FEM analysis"); - doCommand(Doc,"App.activeDocument().addObject('Fem::FemAnalysis','%s')",AnalysisName.c_str()); - doCommand(Doc,"App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject','%s')",MeshName.c_str()); - doCommand(Doc,"App.activeDocument().ActiveObject.Shape = App.activeDocument().%s",base->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s",AnalysisName.c_str(),MeshName.c_str()); - addModule(Gui,"FemGui"); - doCommand(Gui,"FemGui.setActiveAnalysis(App.activeDocument().%s)",AnalysisName.c_str()); - commitCommand(); - - updateActive(); -} - -bool CmdFemCreateAnalysis::isActive(void) -{ - return !FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemAddPart); - -CmdFemAddPart::CmdFemAddPart() - : Command("Fem_FemAddPart") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Add a part to the Analysis"); - sToolTipText = QT_TR_NOOP("Add a part to the Analysis"); - sWhatsThis = "Fem_FemAddPart"; - sStatusTip = sToolTipText; - sPixmap = "fem-add-fem-mesh"; -} - -void CmdFemAddPart::activated(int iMsg) -{ -#ifndef FCWithNetgen - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); - return; -#endif - - std::vector selection = getSelection().getSelectionEx(); - - if (selection.size() != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body. Only one body is allowed.")); - return; - } - - if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("Fillet works only on parts")); - return; - } - - Part::Feature *base = static_cast(selection[0].getObject()); - - std::string AnalysisName = getUniqueObjectName("FemAnalysis"); - std::string MeshName = getUniqueObjectName((std::string(base->getNameInDocument()) +"_Mesh").c_str()); - - openCommand("Create FEM analysis"); - doCommand(Doc,"App.activeDocument().addObject('Fem::FemAnalysis','%s')",AnalysisName.c_str()); - doCommand(Doc,"App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject','%s')",MeshName.c_str()); - doCommand(Doc,"App.activeDocument().ActiveObject.Shape = App.activeDocument().%s",base->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s",AnalysisName.c_str(),MeshName.c_str()); - addModule(Gui,"FemGui"); - doCommand(Gui,"FemGui.setActiveAnalysis(App.activeDocument().%s)",AnalysisName.c_str()); - commitCommand(); - - updateActive(); -} - -bool CmdFemAddPart::isActive(void) -{ - if (Gui::Control().activeDialog()) - return false; - Base::Type type = Base::Type::fromName("Part::Feature"); - return Gui::Selection().countObjectsOfType(type) > 0; -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemCreateSolver); - -CmdFemCreateSolver::CmdFemCreateSolver() - : Command("Fem_CreateSolver") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Add a solver to the Analysis"); - sToolTipText = QT_TR_NOOP("Add a solver to the Analysis"); - sWhatsThis = "Fem_CreateSolver"; - sStatusTip = sToolTipText; - sPixmap = "fem-solver"; -} - -void CmdFemCreateSolver::activated(int iMsg) -{ -#ifndef FCWithNetgen - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); - return; -#endif - - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("Solver"); - - openCommand("Create solver for FEM or CFD analysis"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::FemSolverObject\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemCreateSolver::isActive(void) -{ - return hasActiveDocument(); -} - -//===================================================================================== - - -DEF_STD_CMD_A(CmdFemConstraintBearing); - -CmdFemConstraintBearing::CmdFemConstraintBearing() - : Command("Fem_ConstraintBearing") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM bearing constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a bearing"); - sWhatsThis = "Fem_ConstraintBearing"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-bearing"; -} - -void CmdFemConstraintBearing::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintBearing"); - - openCommand("Make FEM constraint for bearing"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintBearing\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintBearing::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintFixed); - -CmdFemConstraintFixed::CmdFemConstraintFixed() - : Command("Fem_ConstraintFixed") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM fixed constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a fixed geometric entity"); - sWhatsThis = "Fem_ConstraintFixed"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-fixed"; -} - -void CmdFemConstraintFixed::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintFixed"); - - openCommand("Make FEM constraint fixed geometry"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintFixed\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintFixed::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintForce); - -CmdFemConstraintForce::CmdFemConstraintForce() - : Command("Fem_ConstraintForce") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM force constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a force acting on a geometric entity"); - sWhatsThis = "Fem_ConstraintForce"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-force"; -} - -void CmdFemConstraintForce::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintForce"); - - openCommand("Make FEM constraint force on geometry"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintForce\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Force = 1.0",FeatName.c_str()); //OvG: set default not equal to 0 - doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False - doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintForce::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintPressure); - -CmdFemConstraintPressure::CmdFemConstraintPressure() - : Command("Fem_ConstraintPressure") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM pressure constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a pressure acting on a face"); - sWhatsThis = "Fem_ConstraintPressure"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-pressure"; -} - -void CmdFemConstraintPressure::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintPressure"); - - openCommand("Make FEM constraint pressure on face"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPressure\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Pressure = 1000.0",FeatName.c_str()); //OvG: set default not equal to 0 - doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False - doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", - Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintPressure::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintGear); - -CmdFemConstraintGear::CmdFemConstraintGear() - : Command("Fem_ConstraintGear") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM gear constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a gear"); - sWhatsThis = "Fem_ConstraintGear"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-gear"; -} - -void CmdFemConstraintGear::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - std::string FeatName = getUniqueObjectName("FemConstraintGear"); - - openCommand("Make FEM constraint for gear"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintGear\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintGear::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} - -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintPulley); - -CmdFemConstraintPulley::CmdFemConstraintPulley() - : Command("Fem_ConstraintPulley") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM pulley constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a pulley"); - sWhatsThis = "Fem_ConstraintPulley"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-pulley"; -} - -void CmdFemConstraintPulley::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintPulley"); - - openCommand("Make FEM constraint for pulley"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPulley\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Diameter = 300.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.OtherDiameter = 100.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.CenterDistance = 500.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Force = 100.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.TensionForce = 100.0",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintPulley::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} -//===================================================================================== - -DEF_STD_CMD_A(CmdFemConstraintDisplacement); - -CmdFemConstraintDisplacement::CmdFemConstraintDisplacement() - : Command("Fem_ConstraintDisplacement") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM displacement constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint for a displacement acting on a face"); - sWhatsThis = "Fem_ConstraintDisplacement"; - sStatusTip = sToolTipText; - sPixmap = "fem-constraint-displacement"; -} - -void CmdFemConstraintDisplacement::activated(int iMsg) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - std::string FeatName = getUniqueObjectName("FemConstraintDisplacement"); - - openCommand("Make FEM constraint displacement on face"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintDisplacement\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 - doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", - Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); - - doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts - - updateActive(); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -} - -bool CmdFemConstraintDisplacement::isActive(void) -{ - return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); -} -// ##################################################################################################### - - - -DEF_STD_CMD_A(CmdFemDefineNodesSet); - - -void DefineNodesCallback(void * ud, SoEventCallback * n) -{ - Fem::FemAnalysis *Analysis; - - if(getConstraintPrerequisits(&Analysis)) - return; - - // show the wait cursor because this could take quite some time - Gui::WaitCursor wc; - - // When this callback function is invoked we must in either case leave the edit mode - Gui::View3DInventorViewer* view = reinterpret_cast(n->getUserData()); - view->setEditing(false); - view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback,ud); - n->setHandled(); - - SbBool clip_inner; - std::vector clPoly = view->getGLPolygon(&clip_inner); - if (clPoly.size() < 3) - return; - if (clPoly.front() != clPoly.back()) - clPoly.push_back(clPoly.front()); - - SoCamera* cam = view->getSoRenderManager()->getCamera(); - SbViewVolume vv = cam->getViewVolume(); - Gui::ViewVolumeProjection proj(vv); - Base::Polygon2D polygon; - for (std::vector::const_iterator it = clPoly.begin(); it != clPoly.end(); ++it) - polygon.Add(Base::Vector2D((*it)[0],(*it)[1])); - - - std::vector docObj = Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId()); - if(docObj.size() !=1) - return; - - const SMESHDS_Mesh* data = const_cast(dynamic_cast(docObj[0])->FemMesh.getValue().getSMesh())->GetMeshDS(); - - SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator(); - Base::Vector3f pt2d; - std::set IntSet; - - while (aNodeIter->more()) { - const SMDS_MeshNode* aNode = aNodeIter->next(); - Base::Vector3f vec(aNode->X(),aNode->Y(),aNode->Z()); - pt2d = proj(vec); - if (polygon.Contains(Base::Vector2D(pt2d.x, pt2d.y)) == true) - IntSet.insert(aNode->GetID()); - } - - std::stringstream set; - - set << "["; - for(std::set::const_iterator it=IntSet.begin();it!=IntSet.end();++it) - if(it==IntSet.begin()) - set << *it ; - else - set << "," << *it ; - set << "]"; - - - Gui::Command::openCommand("Place robot"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.addObject('Fem::FemSetNodesObject','NodeSet')"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.ActiveObject.Nodes = %s",set.str().c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().NodeSet]",Analysis->getNameInDocument(),Analysis->getNameInDocument()); - ////Gui::Command::updateActive(); - Gui::Command::commitCommand(); - - //std::vector views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId()); - //if (!views.empty()) { - // Gui::Application::Instance->activeDocument()->openCommand("Cut"); - // for (std::vector::iterator it = views.begin(); it != views.end(); ++it) { - // ViewProviderMesh* that = static_cast(*it); - // if (that->getEditingMode() > -1) { - // that->finishEditing(); - // that->cutMesh(clPoly, *view, clip_inner); - // } - // } - - // Gui::Application::Instance->activeDocument()->commitCommand(); - - // view->render(); - //} -} - - - -CmdFemDefineNodesSet::CmdFemDefineNodesSet() - : Command("Fem_DefineNodesSet") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create node set by Poly"); - sToolTipText = QT_TR_NOOP("Create node set by Poly"); - sWhatsThis = "Create node set by Poly"; - sStatusTip = QT_TR_NOOP("Create node set by Poly"); - sPixmap = "fem-fem-mesh-create-node-by-poly"; -} - -void CmdFemDefineNodesSet::activated(int iMsg) -{ - std::vector docObj = Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId()); - - for (std::vector::iterator it = docObj.begin(); it != docObj.end(); ++it) { - if (it == docObj.begin()) { - Gui::Document* doc = getActiveGuiDocument(); - Gui::MDIView* view = doc->getActiveView(); - if (view->getTypeId().isDerivedFrom(Gui::View3DInventor::getClassTypeId())) { - Gui::View3DInventorViewer* viewer = ((Gui::View3DInventor*)view)->getViewer(); - viewer->setEditing(true); - viewer->startSelection(Gui::View3DInventorViewer::Clip); - viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback); - } - else { - return; - } - } - - //Gui::ViewProvider* pVP = getActiveGuiDocument()->getViewProvider(*it); - //if (pVP->isVisible()) - // pVP->startEditing(); - } -} - -bool CmdFemDefineNodesSet::isActive(void) -{ - // Check for the selected mesh feature (all Mesh types) - if (getSelection().countObjectsOfType(Fem::FemMeshObject::getClassTypeId()) != 1) - return false; - - Gui::MDIView* view = Gui::getMainWindow()->activeWindow(); - if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) { - Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); - return !viewer->isEditing(); - } - - return false; -} - - -// ##################################################################################################### - -DEF_STD_CMD_A(CmdFemCreateNodesSet); - -CmdFemCreateNodesSet::CmdFemCreateNodesSet() - : Command("Fem_CreateNodesSet") -{ - sAppModule = "Fem"; - sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Define/create a nodes set..."); - sToolTipText = QT_TR_NOOP("Define/create a nodes set..."); - sWhatsThis = "Fem_CreateNodesSet"; - sStatusTip = sToolTipText; - sPixmap = "fem-fem-mesh-create-node-by-poly"; -} - -void CmdFemCreateNodesSet::activated(int iMsg) -{ - Gui::SelectionFilter ObjectFilter("SELECT Fem::FemSetNodesObject COUNT 1"); - Gui::SelectionFilter FemMeshFilter("SELECT Fem::FemMeshObject COUNT 1"); - - if (ObjectFilter.match()) { - Fem::FemSetNodesObject *NodesObj = static_cast(ObjectFilter.Result[0][0].getObject()); - openCommand("Edit nodes set"); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",NodesObj->getNameInDocument()); - } - else if (FemMeshFilter.match()) { - Fem::FemMeshObject *MeshObj = static_cast(FemMeshFilter.Result[0][0].getObject()); - - std::string FeatName = getUniqueObjectName("NodesSet"); - - openCommand("Create nodes set"); - doCommand(Doc,"App.activeDocument().addObject('Fem::FemSetNodesObject','%s')",FeatName.c_str()); - doCommand(Gui,"App.activeDocument().%s.FemMesh = App.activeDocument().%s",FeatName.c_str(),MeshObj->getNameInDocument()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - else { - QMessageBox::warning(Gui::getMainWindow(), - qApp->translate("CmdFemCreateNodesSet", "Wrong selection"), - qApp->translate("CmdFemCreateNodesSet", "Select a single FEM mesh or nodes set, please.")); - } -} - -bool CmdFemCreateNodesSet::isActive(void) -{ - return hasActiveDocument(); -} - -//-------------------------------------------------------------------------------------- - - -void CreateFemCommands(void) -{ - Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); - //rcCmdMgr.addCommand(new CmdFemCreateAnalysis()); - rcCmdMgr.addCommand(new CmdFemAddPart()); - //rcCmdMgr.addCommand(new CmdFemCreateSolver()); // Solver will be extended and created in python - rcCmdMgr.addCommand(new CmdFemCreateNodesSet()); - rcCmdMgr.addCommand(new CmdFemDefineNodesSet()); - rcCmdMgr.addCommand(new CmdFemConstraintBearing()); - rcCmdMgr.addCommand(new CmdFemConstraintFixed()); - rcCmdMgr.addCommand(new CmdFemConstraintForce()); - rcCmdMgr.addCommand(new CmdFemConstraintPressure()); - rcCmdMgr.addCommand(new CmdFemConstraintGear()); - rcCmdMgr.addCommand(new CmdFemConstraintPulley()); - rcCmdMgr.addCommand(new CmdFemConstraintDisplacement()); -} +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 +# include +# include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ActiveAnalysisObserver.h" + +using namespace std; + + +bool getConstraintPrerequisits(Fem::FemAnalysis **Analysis) +{ + Fem::FemAnalysis* ActiveAnalysis = FemGui::ActiveAnalysisObserver::instance()->getActiveObject(); + if (!ActiveAnalysis || !ActiveAnalysis->getTypeId().isDerivedFrom(Fem::FemAnalysis::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Analysis"), + QObject::tr("You need to create or activate a Analysis")); + return true; + } + + *Analysis = static_cast(ActiveAnalysis); + + // return with no error + return false; + +} + +//OvG: Visibility automation show parts and hide meshes on activation of a constraint +std::string gethideMeshShowPartStr(std::string showConstr="") +{ + return "for amesh in App.activeDocument().Objects:\n\ + if \""+showConstr+"\" == amesh.Name:\n\ + amesh.ViewObject.Visibility = True\n\ + elif \"Mesh\" in amesh.TypeId:\n\ + aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ + for apart in App.activeDocument().Objects:\n\ + if aparttoshow == apart.Name:\n\ + apart.ViewObject.Visibility = True\n\ + amesh.ViewObject.Visibility = False\n"; +} + +//===================================================================================== +DEF_STD_CMD_A(CmdFemCreateAnalysis); + +CmdFemCreateAnalysis::CmdFemCreateAnalysis() + : Command("Fem_CreateAnalysis") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create a FEM analysis"); + sToolTipText = QT_TR_NOOP("Create a FEM analysis"); + sWhatsThis = "Fem_CreateAnalysis"; + sStatusTip = sToolTipText; + sPixmap = "fem-analysis"; +} + +void CmdFemCreateAnalysis::activated(int iMsg) +{ +#ifndef FCWithNetgen + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); + return; +#endif + + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Fillet works only on parts")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + std::string AnalysisName = getUniqueObjectName("FemAnalysis"); + + std::string MeshName = getUniqueObjectName((std::string(base->getNameInDocument()) +"_Mesh").c_str()); + + + openCommand("Create FEM analysis"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemAnalysis','%s')",AnalysisName.c_str()); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject','%s')",MeshName.c_str()); + doCommand(Doc,"App.activeDocument().ActiveObject.Shape = App.activeDocument().%s",base->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s",AnalysisName.c_str(),MeshName.c_str()); + addModule(Gui,"FemGui"); + doCommand(Gui,"FemGui.setActiveAnalysis(App.activeDocument().%s)",AnalysisName.c_str()); + commitCommand(); + + updateActive(); +} + +bool CmdFemCreateAnalysis::isActive(void) +{ + return !FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemAddPart); + +CmdFemAddPart::CmdFemAddPart() + : Command("Fem_FemAddPart") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Add a part to the Analysis"); + sToolTipText = QT_TR_NOOP("Add a part to the Analysis"); + sWhatsThis = "Fem_FemAddPart"; + sStatusTip = sToolTipText; + sPixmap = "fem-add-fem-mesh"; +} + +void CmdFemAddPart::activated(int iMsg) +{ +#ifndef FCWithNetgen + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); + return; +#endif + + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Fillet works only on parts")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + std::string AnalysisName = getUniqueObjectName("FemAnalysis"); + std::string MeshName = getUniqueObjectName((std::string(base->getNameInDocument()) +"_Mesh").c_str()); + + openCommand("Create FEM analysis"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemAnalysis','%s')",AnalysisName.c_str()); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject','%s')",MeshName.c_str()); + doCommand(Doc,"App.activeDocument().ActiveObject.Shape = App.activeDocument().%s",base->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s",AnalysisName.c_str(),MeshName.c_str()); + addModule(Gui,"FemGui"); + doCommand(Gui,"FemGui.setActiveAnalysis(App.activeDocument().%s)",AnalysisName.c_str()); + commitCommand(); + + updateActive(); +} + +bool CmdFemAddPart::isActive(void) +{ + if (Gui::Control().activeDialog()) + return false; + Base::Type type = Base::Type::fromName("Part::Feature"); + return Gui::Selection().countObjectsOfType(type) > 0; +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemCreateSolver); + +CmdFemCreateSolver::CmdFemCreateSolver() + : Command("Fem_CreateSolver") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Add a solver to the Analysis"); + sToolTipText = QT_TR_NOOP("Add a solver to the Analysis"); + sWhatsThis = "Fem_CreateSolver"; + sStatusTip = sToolTipText; + sPixmap = "fem-solver"; +} + +void CmdFemCreateSolver::activated(int iMsg) +{ +#ifndef FCWithNetgen + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Your FreeCAD is build without NETGEN support. Meshing will not work....")); + return; +#endif + + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("Solver"); + + openCommand("Create solver for FEM or CFD analysis"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::FemSolverObject\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemCreateSolver::isActive(void) +{ + return hasActiveDocument(); +} + +//===================================================================================== + + +DEF_STD_CMD_A(CmdFemConstraintBearing); + +CmdFemConstraintBearing::CmdFemConstraintBearing() + : Command("Fem_ConstraintBearing") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM bearing constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a bearing"); + sWhatsThis = "Fem_ConstraintBearing"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-bearing"; +} + +void CmdFemConstraintBearing::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintBearing"); + + openCommand("Make FEM constraint for bearing"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintBearing\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintBearing::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintFixed); + +CmdFemConstraintFixed::CmdFemConstraintFixed() + : Command("Fem_ConstraintFixed") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM fixed constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a fixed geometric entity"); + sWhatsThis = "Fem_ConstraintFixed"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-fixed"; +} + +void CmdFemConstraintFixed::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintFixed"); + + openCommand("Make FEM constraint fixed geometry"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintFixed\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintFixed::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintForce); + +CmdFemConstraintForce::CmdFemConstraintForce() + : Command("Fem_ConstraintForce") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM force constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a force acting on a geometric entity"); + sWhatsThis = "Fem_ConstraintForce"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-force"; +} + +void CmdFemConstraintForce::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintForce"); + + openCommand("Make FEM constraint force on geometry"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintForce\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Force = 1.0",FeatName.c_str()); //OvG: set default not equal to 0 + doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintForce::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintPressure); + +CmdFemConstraintPressure::CmdFemConstraintPressure() + : Command("Fem_ConstraintPressure") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM pressure constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a pressure acting on a face"); + sWhatsThis = "Fem_ConstraintPressure"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-pressure"; +} + +void CmdFemConstraintPressure::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintPressure"); + + openCommand("Make FEM constraint pressure on face"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPressure\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Pressure = 1000.0",FeatName.c_str()); //OvG: set default not equal to 0 + doCommand(Doc,"App.activeDocument().%s.Reversed = False",FeatName.c_str()); //OvG: set default to False + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", + Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintPressure::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintGear); + +CmdFemConstraintGear::CmdFemConstraintGear() + : Command("Fem_ConstraintGear") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM gear constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a gear"); + sWhatsThis = "Fem_ConstraintGear"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-gear"; +} + +void CmdFemConstraintGear::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + std::string FeatName = getUniqueObjectName("FemConstraintGear"); + + openCommand("Make FEM constraint for gear"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintGear\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintGear::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} + +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintPulley); + +CmdFemConstraintPulley::CmdFemConstraintPulley() + : Command("Fem_ConstraintPulley") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM pulley constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a pulley"); + sWhatsThis = "Fem_ConstraintPulley"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-pulley"; +} + +void CmdFemConstraintPulley::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintPulley"); + + openCommand("Make FEM constraint for pulley"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPulley\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Diameter = 300.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.OtherDiameter = 100.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.CenterDistance = 500.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Force = 100.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.TensionForce = 100.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]",Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintPulley::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} +//===================================================================================== + +DEF_STD_CMD_A(CmdFemConstraintDisplacement); + +CmdFemConstraintDisplacement::CmdFemConstraintDisplacement() + : Command("Fem_ConstraintDisplacement") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM displacement constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a displacement acting on a face"); + sWhatsThis = "Fem_ConstraintDisplacement"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-displacement"; +} + +void CmdFemConstraintDisplacement::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintDisplacement"); + + openCommand("Make FEM constraint displacement on face"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintDisplacement\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); //OvG: set initial scale to 1 + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", + Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintDisplacement::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} +// ##################################################################################################### + + + +DEF_STD_CMD_A(CmdFemDefineNodesSet); + + +void DefineNodesCallback(void * ud, SoEventCallback * n) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + // show the wait cursor because this could take quite some time + Gui::WaitCursor wc; + + // When this callback function is invoked we must in either case leave the edit mode + Gui::View3DInventorViewer* view = reinterpret_cast(n->getUserData()); + view->setEditing(false); + view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback,ud); + n->setHandled(); + + SbBool clip_inner; + std::vector clPoly = view->getGLPolygon(&clip_inner); + if (clPoly.size() < 3) + return; + if (clPoly.front() != clPoly.back()) + clPoly.push_back(clPoly.front()); + + SoCamera* cam = view->getSoRenderManager()->getCamera(); + SbViewVolume vv = cam->getViewVolume(); + Gui::ViewVolumeProjection proj(vv); + Base::Polygon2D polygon; + for (std::vector::const_iterator it = clPoly.begin(); it != clPoly.end(); ++it) + polygon.Add(Base::Vector2D((*it)[0],(*it)[1])); + + + std::vector docObj = Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId()); + if(docObj.size() !=1) + return; + + const SMESHDS_Mesh* data = const_cast(dynamic_cast(docObj[0])->FemMesh.getValue().getSMesh())->GetMeshDS(); + + SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator(); + Base::Vector3f pt2d; + std::set IntSet; + + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3f vec(aNode->X(),aNode->Y(),aNode->Z()); + pt2d = proj(vec); + if (polygon.Contains(Base::Vector2D(pt2d.x, pt2d.y)) == true) + IntSet.insert(aNode->GetID()); + } + + std::stringstream set; + + set << "["; + for(std::set::const_iterator it=IntSet.begin();it!=IntSet.end();++it) + if(it==IntSet.begin()) + set << *it ; + else + set << "," << *it ; + set << "]"; + + + Gui::Command::openCommand("Place robot"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.addObject('Fem::FemSetNodesObject','NodeSet')"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.ActiveObject.Nodes = %s",set.str().c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().NodeSet]",Analysis->getNameInDocument(),Analysis->getNameInDocument()); + ////Gui::Command::updateActive(); + Gui::Command::commitCommand(); + + //std::vector views = view->getViewProvidersOfType(ViewProviderMesh::getClassTypeId()); + //if (!views.empty()) { + // Gui::Application::Instance->activeDocument()->openCommand("Cut"); + // for (std::vector::iterator it = views.begin(); it != views.end(); ++it) { + // ViewProviderMesh* that = static_cast(*it); + // if (that->getEditingMode() > -1) { + // that->finishEditing(); + // that->cutMesh(clPoly, *view, clip_inner); + // } + // } + + // Gui::Application::Instance->activeDocument()->commitCommand(); + + // view->render(); + //} +} + + + +CmdFemDefineNodesSet::CmdFemDefineNodesSet() + : Command("Fem_DefineNodesSet") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create node set by Poly"); + sToolTipText = QT_TR_NOOP("Create node set by Poly"); + sWhatsThis = "Create node set by Poly"; + sStatusTip = QT_TR_NOOP("Create node set by Poly"); + sPixmap = "fem-fem-mesh-create-node-by-poly"; +} + +void CmdFemDefineNodesSet::activated(int iMsg) +{ + std::vector docObj = Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId()); + + for (std::vector::iterator it = docObj.begin(); it != docObj.end(); ++it) { + if (it == docObj.begin()) { + Gui::Document* doc = getActiveGuiDocument(); + Gui::MDIView* view = doc->getActiveView(); + if (view->getTypeId().isDerivedFrom(Gui::View3DInventor::getClassTypeId())) { + Gui::View3DInventorViewer* viewer = ((Gui::View3DInventor*)view)->getViewer(); + viewer->setEditing(true); + viewer->startSelection(Gui::View3DInventorViewer::Clip); + viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback); + } + else { + return; + } + } + + //Gui::ViewProvider* pVP = getActiveGuiDocument()->getViewProvider(*it); + //if (pVP->isVisible()) + // pVP->startEditing(); + } +} + +bool CmdFemDefineNodesSet::isActive(void) +{ + // Check for the selected mesh feature (all Mesh types) + if (getSelection().countObjectsOfType(Fem::FemMeshObject::getClassTypeId()) != 1) + return false; + + Gui::MDIView* view = Gui::getMainWindow()->activeWindow(); + if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) { + Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); + return !viewer->isEditing(); + } + + return false; +} + + +// ##################################################################################################### + +DEF_STD_CMD_A(CmdFemCreateNodesSet); + +CmdFemCreateNodesSet::CmdFemCreateNodesSet() + : Command("Fem_CreateNodesSet") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Define/create a nodes set..."); + sToolTipText = QT_TR_NOOP("Define/create a nodes set..."); + sWhatsThis = "Fem_CreateNodesSet"; + sStatusTip = sToolTipText; + sPixmap = "fem-fem-mesh-create-node-by-poly"; +} + +void CmdFemCreateNodesSet::activated(int iMsg) +{ + Gui::SelectionFilter ObjectFilter("SELECT Fem::FemSetNodesObject COUNT 1"); + Gui::SelectionFilter FemMeshFilter("SELECT Fem::FemMeshObject COUNT 1"); + + if (ObjectFilter.match()) { + Fem::FemSetNodesObject *NodesObj = static_cast(ObjectFilter.Result[0][0].getObject()); + openCommand("Edit nodes set"); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",NodesObj->getNameInDocument()); + } + else if (FemMeshFilter.match()) { + Fem::FemMeshObject *MeshObj = static_cast(FemMeshFilter.Result[0][0].getObject()); + + std::string FeatName = getUniqueObjectName("NodesSet"); + + openCommand("Create nodes set"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemSetNodesObject','%s')",FeatName.c_str()); + doCommand(Gui,"App.activeDocument().%s.FemMesh = App.activeDocument().%s",FeatName.c_str(),MeshObj->getNameInDocument()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + else { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("CmdFemCreateNodesSet", "Wrong selection"), + qApp->translate("CmdFemCreateNodesSet", "Select a single FEM mesh or nodes set, please.")); + } +} + +bool CmdFemCreateNodesSet::isActive(void) +{ + return hasActiveDocument(); +} + +//-------------------------------------------------------------------------------------- + + +void CreateFemCommands(void) +{ + Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); + //rcCmdMgr.addCommand(new CmdFemCreateAnalysis()); + rcCmdMgr.addCommand(new CmdFemAddPart()); + //rcCmdMgr.addCommand(new CmdFemCreateSolver()); // Solver will be extended and created in python + rcCmdMgr.addCommand(new CmdFemCreateNodesSet()); + rcCmdMgr.addCommand(new CmdFemDefineNodesSet()); + rcCmdMgr.addCommand(new CmdFemConstraintBearing()); + rcCmdMgr.addCommand(new CmdFemConstraintFixed()); + rcCmdMgr.addCommand(new CmdFemConstraintForce()); + rcCmdMgr.addCommand(new CmdFemConstraintPressure()); + rcCmdMgr.addCommand(new CmdFemConstraintGear()); + rcCmdMgr.addCommand(new CmdFemConstraintPulley()); + rcCmdMgr.addCommand(new CmdFemConstraintDisplacement()); +} diff --git a/src/Mod/Fem/Gui/PreCompiled.cpp b/src/Mod/Fem/Gui/PreCompiled.cpp index 46269e9671fe..12e9b02f9747 100644 --- a/src/Mod/Fem/Gui/PreCompiled.cpp +++ b/src/Mod/Fem/Gui/PreCompiled.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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" +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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" diff --git a/src/Mod/Fem/Gui/PreCompiled.h b/src/Mod/Fem/Gui/PreCompiled.h index 616dd7c07928..94309cd4ce82 100644 --- a/src/Mod/Fem/Gui/PreCompiled.h +++ b/src/Mod/Fem/Gui/PreCompiled.h @@ -1,81 +1,81 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen 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 * - * * - ***************************************************************************/ - - -#ifndef FEMGUI_PRECOMPILED_H -#define FEMGUI_PRECOMPILED_H - -#include - -// Importing of App classes -#ifdef FC_OS_WIN32 -# define AppFemExport __declspec(dllimport) -# define PartExport __declspec(dllimport) -# define FemGuiExport __declspec(dllexport) -#else // for Linux -# define PartExport -# define AppFemExport -# define FemGuiExport -#endif - -#ifdef _MSC_VER -# pragma warning(disable : 4005) -# pragma warning(disable : 4290) -#endif - -#ifdef _PreComp_ +/*************************************************************************** + * Copyright (c) 2008 Jürgen 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 * + * * + ***************************************************************************/ + + +#ifndef FEMGUI_PRECOMPILED_H +#define FEMGUI_PRECOMPILED_H + +#include + +// Importing of App classes +#ifdef FC_OS_WIN32 +# define AppFemExport __declspec(dllimport) +# define PartExport __declspec(dllimport) +# define FemGuiExport __declspec(dllexport) +#else // for Linux +# define PartExport +# define AppFemExport +# define FemGuiExport +#endif + +#ifdef _MSC_VER +# pragma warning(disable : 4005) +# pragma warning(disable : 4290) +#endif + +#ifdef _PreComp_ // Python -#include - -// standard -#include -#include -#include - -// STL -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// boost -#include - -#ifdef FC_OS_WIN32 -# include -#endif - - -// Qt Toolkit -#ifndef __Qt4All__ -# include -#endif +#include + +// standard +#include +#include +#include + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// boost +#include + +#ifdef FC_OS_WIN32 +# include +#endif + + +// Qt Toolkit +#ifndef __Qt4All__ +# include +#endif + +#endif //_PreComp_ -#endif //_PreComp_ - -#endif // FEMGUI_PRECOMPILED_H +#endif // FEMGUI_PRECOMPILED_H diff --git a/src/Mod/Fem/Gui/Resources/Fem.qrc b/src/Mod/Fem/Gui/Resources/Fem.qrc index a9a4142397b2..0f81d4f0a9d3 100755 --- a/src/Mod/Fem/Gui/Resources/Fem.qrc +++ b/src/Mod/Fem/Gui/Resources/Fem.qrc @@ -1,55 +1,55 @@ - - - icons/fem-fem-mesh-from-shape.svg - icons/fem-fem-mesh-create-node-by-poly.svg - icons/fem-analysis.svg - icons/fem-solver.svg - icons/fem-constraint-displacement.svg - icons/fem-constraint-force.svg - icons/fem-constraint-fixed.svg - icons/fem-constraint-pressure.svg - icons/fem-constraint-bearing.svg - icons/fem-constraint-gear.svg - icons/fem-constraint-pulley.svg - icons/fem-add-fem-mesh.svg - icons/fem-add-material.svg - icons/fem-add-part.svg - icons/fem-inp-editor.svg - icons/fem-material.svg - icons/fem-new-analysis.svg - icons/fem-purge-results.svg - icons/fem-quick-analysis.svg - icons/fem-frequency-analysis.svg - icons/fem-result.svg - icons/fem-shell-thickness.svg - icons/fem-beam-section.svg - icons/preferences-fem.svg - icons/FemWorkbench.svg - translations/Fem_af.qm - translations/Fem_de.qm - translations/Fem_fi.qm - translations/Fem_fr.qm - translations/Fem_hr.qm - translations/Fem_it.qm - translations/Fem_nl.qm - translations/Fem_no.qm - translations/Fem_pl.qm - translations/Fem_ru.qm - translations/Fem_uk.qm - translations/Fem_tr.qm - translations/Fem_sv-SE.qm - translations/Fem_zh-TW.qm - translations/Fem_pt-BR.qm - translations/Fem_cs.qm - translations/Fem_sk.qm - translations/Fem_es-ES.qm - translations/Fem_zh-CN.qm - translations/Fem_ja.qm - translations/Fem_ro.qm - translations/Fem_hu.qm - translations/Fem_pt-PT.qm - translations/Fem_sr.qm - translations/Fem_el.qm - translations/Fem_sl.qm - - + + + icons/fem-fem-mesh-from-shape.svg + icons/fem-fem-mesh-create-node-by-poly.svg + icons/fem-analysis.svg + icons/fem-solver.svg + icons/fem-constraint-displacement.svg + icons/fem-constraint-force.svg + icons/fem-constraint-fixed.svg + icons/fem-constraint-pressure.svg + icons/fem-constraint-bearing.svg + icons/fem-constraint-gear.svg + icons/fem-constraint-pulley.svg + icons/fem-add-fem-mesh.svg + icons/fem-add-material.svg + icons/fem-add-part.svg + icons/fem-inp-editor.svg + icons/fem-material.svg + icons/fem-new-analysis.svg + icons/fem-purge-results.svg + icons/fem-quick-analysis.svg + icons/fem-frequency-analysis.svg + icons/fem-result.svg + icons/fem-shell-thickness.svg + icons/fem-beam-section.svg + icons/preferences-fem.svg + icons/FemWorkbench.svg + translations/Fem_af.qm + translations/Fem_de.qm + translations/Fem_fi.qm + translations/Fem_fr.qm + translations/Fem_hr.qm + translations/Fem_it.qm + translations/Fem_nl.qm + translations/Fem_no.qm + translations/Fem_pl.qm + translations/Fem_ru.qm + translations/Fem_uk.qm + translations/Fem_tr.qm + translations/Fem_sv-SE.qm + translations/Fem_zh-TW.qm + translations/Fem_pt-BR.qm + translations/Fem_cs.qm + translations/Fem_sk.qm + translations/Fem_es-ES.qm + translations/Fem_zh-CN.qm + translations/Fem_ja.qm + translations/Fem_ro.qm + translations/Fem_hu.qm + translations/Fem_pt-PT.qm + translations/Fem_sr.qm + translations/Fem_el.qm + translations/Fem_sl.qm + + diff --git a/src/Mod/Fem/Gui/Resources/UpdateResources.bat b/src/Mod/Fem/Gui/Resources/UpdateResources.bat index 11b80d703aea..51a439812bef 100755 --- a/src/Mod/Fem/Gui/Resources/UpdateResources.bat +++ b/src/Mod/Fem/Gui/Resources/UpdateResources.bat @@ -1,2 +1,2 @@ -python ..\..\..\..\Tools\dir2qrc.py -v -o Fem.qrc -@pause +python ..\..\..\..\Tools\dir2qrc.py -v -o Fem.qrc +@pause diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.cpp b/src/Mod/Fem/Gui/TaskFemConstraint.cpp index 66ca6532052a..d44c9fb693f2 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraint.cpp @@ -1,228 +1,228 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskFemConstraint.h" -#include "TaskFemConstraint.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -# include //OvG conversion between string and int etc. - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraint */ - -TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent,const char* pixmapname) - : TaskBox(Gui::BitmapFactory().pixmap(pixmapname),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView) -{ - selectionMode = selref; - - // Setup the dialog inside the Shaft Wizard dialog - if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL)) { - // Hide the shaft wizard table widget to make more space - ConstraintView->wizardSubLayout->itemAt(0)->widget()->hide(); - QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild(); - for (int b = 0; b < buttons->count(); b++) - buttons->itemAt(b)->widget()->hide(); - - // Show this dialog for the FEM constraint - ConstraintView->wizardWidget->addWidget(this); - - // Add buttons to finish editing the constraint without closing the shaft wizard dialog - okButton = new QPushButton(QObject::tr("Ok")); - cancelButton = new QPushButton(QObject::tr("Cancel")); - buttonBox = new QDialogButtonBox(); - buttonBox->addButton(okButton, QDialogButtonBox::AcceptRole); - buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole); - QObject::connect(okButton, SIGNAL(clicked()), this, SLOT(onButtonWizOk())); - QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(onButtonWizCancel())); - ConstraintView->wizardWidget->addWidget(buttonBox); - } -} - -void TaskFemConstraint::keyPressEvent(QKeyEvent *ke) -{ - if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL)) - // Prevent from closing this dialog AND the shaft wizard dialog - // TODO: This should trigger an update in the shaft wizard but its difficult to access a python dialog from here... - if (ke->key() == Qt::Key_Return) - return; - - TaskBox::keyPressEvent(ke); -} - -const std::string TaskFemConstraint::getReferences(const std::vector& items) const -{ - std::string result; - for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { - int pos = i->find_last_of(":"); - std::string objStr = "App.ActiveDocument." + i->substr(0, pos); - std::string refStr = "\"" + i->substr(pos+1) + "\""; - result = result + (i != items.begin() ? ", " : "") + "(" + objStr + "," + refStr + ")"; - } - - return result; -} - -const std::string TaskFemConstraint::getScale() const //OvG: Return pre-calculated scale for constraint display -{ - std::string result; - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - result = boost::lexical_cast(pcConstraint->Scale.getValue()); - return result; -} - -void TaskFemConstraint::onReferenceDeleted(const int row) { - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - Objects.erase(Objects.begin() + row); - SubElements.erase(SubElements.begin() + row); - pcConstraint->References.setValues(Objects, SubElements); -} - -void TaskFemConstraint::onButtonReference(const bool pressed) { - if (pressed) - selectionMode = selref; - else - selectionMode = selnone; - Gui::Selection().clearSelection(); -} - -void TaskFemConstraint::onButtonWizOk() -{ - // Remove dialog elements - buttonBox->removeButton(okButton); - delete okButton; - buttonBox->removeButton(cancelButton); - delete cancelButton; - ConstraintView->wizardWidget->removeWidget(buttonBox); - delete buttonBox; - ConstraintView->wizardWidget->removeWidget(this); - - // Show the wizard shaft dialog again - ConstraintView->wizardSubLayout->itemAt(0)->widget()->show(); - QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild(); - for (int b = 0; b < buttons->count(); b++) - buttons->itemAt(b)->widget()->show(); - - Gui::Application::Instance->activeDocument()->resetEdit(); // Reaches ViewProviderFemConstraint::unsetEdit() eventually -} - -void TaskFemConstraint::onButtonWizCancel() -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - if (pcConstraint != NULL) - pcConstraint->getDocument()->remObject(pcConstraint->getNameInDocument()); - onButtonWizOk(); -} - -const QString TaskFemConstraint::makeRefText(const App::DocumentObject* obj, const std::string& subName) const -{ - return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str()); -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//==== calls from the TaskView =============================================================== - -void TaskDlgFemConstraint::open() -{ - ConstraintView->setVisible(true); - Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts -} - -bool TaskDlgFemConstraint::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - - try { - std::string refs = parameter->getReferences(); - - if (!refs.empty()) { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.References = [%s]", name.c_str(), refs.c_str()); - } else { - QMessageBox::warning(parameter, tr("Input error"), tr("You must specify at least one reference")); - return false; - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); - if (!ConstraintView->getObject()->isValid()) - throw Base::Exception(ConstraintView->getObject()->getStatusString()); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::commitCommand(); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return true; -} - -bool TaskDlgFemConstraint::reject() -{ - // roll back the changes - Gui::Command::abortCommand(); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - - return true; -} - - -#include "moc_TaskFemConstraint.cpp" +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraint.h" +#include "TaskFemConstraint.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +# include //OvG conversion between string and int etc. + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraint */ + +TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent,const char* pixmapname) + : TaskBox(Gui::BitmapFactory().pixmap(pixmapname),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView) +{ + selectionMode = selref; + + // Setup the dialog inside the Shaft Wizard dialog + if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL)) { + // Hide the shaft wizard table widget to make more space + ConstraintView->wizardSubLayout->itemAt(0)->widget()->hide(); + QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild(); + for (int b = 0; b < buttons->count(); b++) + buttons->itemAt(b)->widget()->hide(); + + // Show this dialog for the FEM constraint + ConstraintView->wizardWidget->addWidget(this); + + // Add buttons to finish editing the constraint without closing the shaft wizard dialog + okButton = new QPushButton(QObject::tr("Ok")); + cancelButton = new QPushButton(QObject::tr("Cancel")); + buttonBox = new QDialogButtonBox(); + buttonBox->addButton(okButton, QDialogButtonBox::AcceptRole); + buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole); + QObject::connect(okButton, SIGNAL(clicked()), this, SLOT(onButtonWizOk())); + QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(onButtonWizCancel())); + ConstraintView->wizardWidget->addWidget(buttonBox); + } +} + +void TaskFemConstraint::keyPressEvent(QKeyEvent *ke) +{ + if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL)) + // Prevent from closing this dialog AND the shaft wizard dialog + // TODO: This should trigger an update in the shaft wizard but its difficult to access a python dialog from here... + if (ke->key() == Qt::Key_Return) + return; + + TaskBox::keyPressEvent(ke); +} + +const std::string TaskFemConstraint::getReferences(const std::vector& items) const +{ + std::string result; + for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { + int pos = i->find_last_of(":"); + std::string objStr = "App.ActiveDocument." + i->substr(0, pos); + std::string refStr = "\"" + i->substr(pos+1) + "\""; + result = result + (i != items.begin() ? ", " : "") + "(" + objStr + "," + refStr + ")"; + } + + return result; +} + +const std::string TaskFemConstraint::getScale() const //OvG: Return pre-calculated scale for constraint display +{ + std::string result; + Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); + result = boost::lexical_cast(pcConstraint->Scale.getValue()); + return result; +} + +void TaskFemConstraint::onReferenceDeleted(const int row) { + Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + Objects.erase(Objects.begin() + row); + SubElements.erase(SubElements.begin() + row); + pcConstraint->References.setValues(Objects, SubElements); +} + +void TaskFemConstraint::onButtonReference(const bool pressed) { + if (pressed) + selectionMode = selref; + else + selectionMode = selnone; + Gui::Selection().clearSelection(); +} + +void TaskFemConstraint::onButtonWizOk() +{ + // Remove dialog elements + buttonBox->removeButton(okButton); + delete okButton; + buttonBox->removeButton(cancelButton); + delete cancelButton; + ConstraintView->wizardWidget->removeWidget(buttonBox); + delete buttonBox; + ConstraintView->wizardWidget->removeWidget(this); + + // Show the wizard shaft dialog again + ConstraintView->wizardSubLayout->itemAt(0)->widget()->show(); + QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild(); + for (int b = 0; b < buttons->count(); b++) + buttons->itemAt(b)->widget()->show(); + + Gui::Application::Instance->activeDocument()->resetEdit(); // Reaches ViewProviderFemConstraint::unsetEdit() eventually +} + +void TaskFemConstraint::onButtonWizCancel() +{ + Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); + if (pcConstraint != NULL) + pcConstraint->getDocument()->remObject(pcConstraint->getNameInDocument()); + onButtonWizOk(); +} + +const QString TaskFemConstraint::makeRefText(const App::DocumentObject* obj, const std::string& subName) const +{ + return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str()); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//==== calls from the TaskView =============================================================== + +void TaskDlgFemConstraint::open() +{ + ConstraintView->setVisible(true); + Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts +} + +bool TaskDlgFemConstraint::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + + try { + std::string refs = parameter->getReferences(); + + if (!refs.empty()) { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.References = [%s]", name.c_str(), refs.c_str()); + } else { + QMessageBox::warning(parameter, tr("Input error"), tr("You must specify at least one reference")); + return false; + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!ConstraintView->getObject()->isValid()) + throw Base::Exception(ConstraintView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +bool TaskDlgFemConstraint::reject() +{ + // roll back the changes + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + + return true; +} + + +#include "moc_TaskFemConstraint.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.h b/src/Mod/Fem/Gui/TaskFemConstraint.h index 9108c25eafc0..343b4dbdc1a9 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.h +++ b/src/Mod/Fem/Gui/TaskFemConstraint.h @@ -1,108 +1,108 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraint_H -#define GUI_TASKVIEW_TaskFemConstraint_H - -#include -#include -#include - -#include "ViewProviderFemConstraint.h" - -namespace FemGui { - -class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionObserver -{ - Q_OBJECT - -public: - TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,const char* pixmapname = ""); - virtual ~TaskFemConstraint() {} - - virtual const std::string getReferences(void) const {return std::string();} - const std::string getReferences(const std::vector& items) const; - const std::string getScale() const; - -protected Q_SLOTS: - void onReferenceDeleted(const int row); - void onButtonReference(const bool pressed = true); - // Shaft Wizard integration - void onButtonWizOk(); - void onButtonWizCancel(); - -protected: - virtual void changeEvent(QEvent *e) { TaskBox::changeEvent(e); } - const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const; - virtual void keyPressEvent(QKeyEvent * ke); - -private: - virtual void onSelectionChanged(const Gui::SelectionChanges&) {} - -protected: - QWidget* proxy; - ViewProviderFemConstraint *ConstraintView; - enum {seldir, selref, selloc, selnone} selectionMode; - -private: - // This seems to be the only way to access the widgets again in order to remove them from the dialog - QDialogButtonBox* buttonBox; - QPushButton* okButton; - QPushButton* cancelButton; -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog -{ - Q_OBJECT - -public: - - /// is called the TaskView when the dialog is opened - void open(); - /* - /// is called by the framework if an button is clicked which has no accept or reject role - virtual void clicked(int) {} - /// is called by the framework if the dialog is accepted (Ok) - */ - virtual bool accept(); - /// is called by the framework if the dialog is rejected (Cancel) - virtual bool reject(); - virtual bool isAllowedAlterDocument(void) const - { return false; } - - /// returns for Close and Help button - virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const - { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } - - ViewProviderFemConstraint* getConstraintView() const - { return ConstraintView; } - -protected: - ViewProviderFemConstraint *ConstraintView; - TaskFemConstraint *parameter; -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraint_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraint_H +#define GUI_TASKVIEW_TaskFemConstraint_H + +#include +#include +#include + +#include "ViewProviderFemConstraint.h" + +namespace FemGui { + +class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionObserver +{ + Q_OBJECT + +public: + TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,const char* pixmapname = ""); + virtual ~TaskFemConstraint() {} + + virtual const std::string getReferences(void) const {return std::string();} + const std::string getReferences(const std::vector& items) const; + const std::string getScale() const; + +protected Q_SLOTS: + void onReferenceDeleted(const int row); + void onButtonReference(const bool pressed = true); + // Shaft Wizard integration + void onButtonWizOk(); + void onButtonWizCancel(); + +protected: + virtual void changeEvent(QEvent *e) { TaskBox::changeEvent(e); } + const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const; + virtual void keyPressEvent(QKeyEvent * ke); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges&) {} + +protected: + QWidget* proxy; + ViewProviderFemConstraint *ConstraintView; + enum {seldir, selref, selloc, selnone} selectionMode; + +private: + // This seems to be the only way to access the widgets again in order to remove them from the dialog + QDialogButtonBox* buttonBox; + QPushButton* okButton; + QPushButton* cancelButton; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + + /// is called the TaskView when the dialog is opened + void open(); + /* + /// is called by the framework if an button is clicked which has no accept or reject role + virtual void clicked(int) {} + /// is called by the framework if the dialog is accepted (Ok) + */ + virtual bool accept(); + /// is called by the framework if the dialog is rejected (Cancel) + virtual bool reject(); + virtual bool isAllowedAlterDocument(void) const + { return false; } + + /// returns for Close and Help button + virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const + { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } + + ViewProviderFemConstraint* getConstraintView() const + { return ConstraintView; } + +protected: + ViewProviderFemConstraint *ConstraintView; + TaskFemConstraint *parameter; +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraint_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp b/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp index 98fcbda430e1..c3992f9d8aa4 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp @@ -1,358 +1,358 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskFemConstraintBearing.h" -#include "TaskFemConstraintBearing.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraintBearing */ - -TaskFemConstraintBearing::TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView,QWidget *parent, - const char *pixmapname) - : TaskFemConstraint(ConstraintView, parent, pixmapname) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskFemConstraintBearing(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - // Create a context menu for the listview of the references - QAction* action = new QAction(tr("Delete"), ui->listReferences); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onReferenceDeleted())); - ui->listReferences->addAction(action); - ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->spinDistance, SIGNAL(valueChanged(double)), - this, SLOT(onDistanceChanged(double))); - connect(ui->buttonReference, SIGNAL(pressed()), - this, SLOT(onButtonReference())); - connect(ui->buttonLocation, SIGNAL(pressed()), - this, SLOT(onButtonLocation())); - connect(ui->checkAxial, SIGNAL(toggled(bool)), - this, SLOT(onCheckAxial(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->spinDistance->blockSignals(true); - ui->listReferences->blockSignals(true); - ui->buttonReference->blockSignals(true); - ui->buttonLocation->blockSignals(true); - ui->checkAxial->blockSignals(true); - - // Get the feature data - Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); - double d = pcConstraint->Dist.getValue(); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - std::vector locStrings = pcConstraint->Location.getSubValues(); - QString loc; - if (!locStrings.empty()) - loc = makeRefText(pcConstraint->Location.getValue(), locStrings.front()); - bool axialfree = pcConstraint->AxialFree.getValue(); - - // Fill data into dialog elements - ui->spinDistance->setMinimum(-FLOAT_MAX); - ui->spinDistance->setMaximum(FLOAT_MAX); - ui->spinDistance->setValue(d); - ui->listReferences->clear(); - for (std::size_t i = 0; i < Objects.size(); i++) - ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); - if (Objects.size() > 0) - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - ui->lineLocation->setText(loc); - ui->checkAxial->setChecked(axialfree); - - // Hide unwanted ui elements - ui->labelDiameter->setVisible(false); - ui->spinDiameter->setVisible(false); - ui->labelOtherDiameter->setVisible(false); - ui->spinOtherDiameter->setVisible(false); - ui->labelCenterDistance->setVisible(false); - ui->spinCenterDistance->setVisible(false); - ui->checkIsDriven->setVisible(false); - ui->labelForce->setVisible(false); - ui->spinForce->setVisible(false); - ui->labelTensionForce->setVisible(false); - ui->spinTensionForce->setVisible(false); - ui->labelForceAngle->setVisible(false); - ui->spinForceAngle->setVisible(false); - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReversed->setVisible(false); - - ui->spinDistance->blockSignals(false); - ui->listReferences->blockSignals(false); - ui->buttonReference->blockSignals(false); - ui->buttonLocation->blockSignals(false); - ui->checkAxial->blockSignals(false); - - onButtonReference(true); -} - -void TaskFemConstraintBearing::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == selref) { - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - if (Objects.size() > 0) { - QMessageBox::warning(this, tr("Selection error"), tr("Please use only a single reference for bearing constraint")); - return; - } - if (subName.substr(0,4) != "Face") { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); - return; - } - - // Only cylindrical faces allowed - BRepAdaptor_Surface surface(TopoDS::Face(ref)); - if (surface.GetType() != GeomAbs_Cylinder) { - QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked")); - return; - } - - // add the new reference - Objects.push_back(obj); - SubElements.push_back(subName); - pcConstraint->References.setValues(Objects,SubElements); - ui->listReferences->addItem(makeRefText(obj, subName)); - - // Turn off reference selection mode - onButtonReference(false); - } - else if (selectionMode == selloc) { - if (subName.substr(0,4) == "Face") { - if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); - return; - } - } - else if (subName.substr(0,4) == "Edge") { - if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); - return; - } - } - else { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); - return; - } - std::vector references(1,subName); - pcConstraint->Location.setValue(obj, references); - ui->lineLocation->setText(makeRefText(obj, subName)); - - // Turn off location selection mode - onButtonLocation(false); - } - - Gui::Selection().clearSelection(); - } -} - -void TaskFemConstraintBearing::onDistanceChanged(double l) -{ - Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Dist.setValue(l); -} - -void TaskFemConstraintBearing::onReferenceDeleted() { - int row = ui->listReferences->currentIndex().row(); - TaskFemConstraint::onReferenceDeleted(row); - ui->listReferences->model()->removeRow(row); - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); -} - -void TaskFemConstraintBearing::onButtonLocation(const bool pressed) { - if (pressed) { - selectionMode = selloc; - } else { - selectionMode = selnone; - } - ui->buttonLocation->setChecked(pressed); - Gui::Selection().clearSelection(); -} - -void TaskFemConstraintBearing::onCheckAxial(const bool pressed) -{ - Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->AxialFree.setValue(pressed); -} - -double TaskFemConstraintBearing::getDistance(void) const -{ - return ui->spinDistance->value(); -} - -const std::string TaskFemConstraintBearing::getReferences() const -{ - int rows = ui->listReferences->model()->rowCount(); - - std::vector items; - for (int r = 0; r < rows; r++) - items.push_back(ui->listReferences->item(r)->text().toStdString()); - return TaskFemConstraint::getReferences(items); -} - -const std::string TaskFemConstraintBearing::getLocationName(void) const -{ - std::string loc = ui->lineLocation->text().toStdString(); - if (loc.empty()) - return ""; - - int pos = loc.find_last_of(":"); - return loc.substr(0, pos).c_str(); -} - -const std::string TaskFemConstraintBearing::getLocationObject(void) const -{ - std::string loc = ui->lineLocation->text().toStdString(); - if (loc.empty()) - return ""; - - int pos = loc.find_last_of(":"); - return loc.substr(pos+1).c_str(); -} - -bool TaskFemConstraintBearing::getAxial() const -{ - return ui->checkAxial->isChecked(); -} - -TaskFemConstraintBearing::~TaskFemConstraintBearing() -{ - delete ui; -} - -void TaskFemConstraintBearing::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->spinDistance->blockSignals(true); - ui->retranslateUi(proxy); - ui->spinDistance->blockSignals(false); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgFemConstraintBearing::TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView) -{ - this->ConstraintView = ConstraintView; - assert(ConstraintView); - this->parameter = new TaskFemConstraintBearing(ConstraintView); - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgFemConstraintBearing::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintBearing* parameterBearing = static_cast(parameter); - - try { - //Gui::Command::openCommand("FEM force constraint changed"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Dist = %f",name.c_str(), parameterBearing->getDistance()); - - std::string locname = parameterBearing->getLocationName().data(); - std::string locobj = parameterBearing->getLocationObject().data(); - - if (!locname.empty()) { - QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromStdString(locname)); - buf = buf.arg(QString::fromStdString(locobj)); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = %s", name.c_str(), buf.toStdString().c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = None", name.c_str()); - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.AxialFree = %s", name.c_str(), parameterBearing->getAxial() ? "True" : "False"); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return TaskDlgFemConstraint::accept(); -} - -#include "moc_TaskFemConstraintBearing.cpp" +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintBearing.h" +#include "TaskFemConstraintBearing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintBearing */ + +TaskFemConstraintBearing::TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView,QWidget *parent, + const char *pixmapname) + : TaskFemConstraint(ConstraintView, parent, pixmapname) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintBearing(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->spinDistance, SIGNAL(valueChanged(double)), + this, SLOT(onDistanceChanged(double))); + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + connect(ui->buttonLocation, SIGNAL(pressed()), + this, SLOT(onButtonLocation())); + connect(ui->checkAxial, SIGNAL(toggled(bool)), + this, SLOT(onCheckAxial(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->spinDistance->blockSignals(true); + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + ui->buttonLocation->blockSignals(true); + ui->checkAxial->blockSignals(true); + + // Get the feature data + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + double d = pcConstraint->Dist.getValue(); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector locStrings = pcConstraint->Location.getSubValues(); + QString loc; + if (!locStrings.empty()) + loc = makeRefText(pcConstraint->Location.getValue(), locStrings.front()); + bool axialfree = pcConstraint->AxialFree.getValue(); + + // Fill data into dialog elements + ui->spinDistance->setMinimum(-FLOAT_MAX); + ui->spinDistance->setMaximum(FLOAT_MAX); + ui->spinDistance->setValue(d); + ui->listReferences->clear(); + for (std::size_t i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + ui->lineLocation->setText(loc); + ui->checkAxial->setChecked(axialfree); + + // Hide unwanted ui elements + ui->labelDiameter->setVisible(false); + ui->spinDiameter->setVisible(false); + ui->labelOtherDiameter->setVisible(false); + ui->spinOtherDiameter->setVisible(false); + ui->labelCenterDistance->setVisible(false); + ui->spinCenterDistance->setVisible(false); + ui->checkIsDriven->setVisible(false); + ui->labelForce->setVisible(false); + ui->spinForce->setVisible(false); + ui->labelTensionForce->setVisible(false); + ui->spinTensionForce->setVisible(false); + ui->labelForceAngle->setVisible(false); + ui->spinForceAngle->setVisible(false); + ui->buttonDirection->setVisible(false); + ui->lineDirection->setVisible(false); + ui->checkReversed->setVisible(false); + + ui->spinDistance->blockSignals(false); + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + ui->buttonLocation->blockSignals(false); + ui->checkAxial->blockSignals(false); + + onButtonReference(true); +} + +void TaskFemConstraintBearing::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + if (Objects.size() > 0) { + QMessageBox::warning(this, tr("Selection error"), tr("Please use only a single reference for bearing constraint")); + return; + } + if (subName.substr(0,4) != "Face") { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); + return; + } + + // Only cylindrical faces allowed + BRepAdaptor_Surface surface(TopoDS::Face(ref)); + if (surface.GetType() != GeomAbs_Cylinder) { + QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked")); + return; + } + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + + // Turn off reference selection mode + onButtonReference(false); + } + else if (selectionMode == selloc) { + if (subName.substr(0,4) == "Face") { + if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); + return; + } + } + else if (subName.substr(0,4) == "Edge") { + if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); + return; + } + } + else { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); + return; + } + std::vector references(1,subName); + pcConstraint->Location.setValue(obj, references); + ui->lineLocation->setText(makeRefText(obj, subName)); + + // Turn off location selection mode + onButtonLocation(false); + } + + Gui::Selection().clearSelection(); + } +} + +void TaskFemConstraintBearing::onDistanceChanged(double l) +{ + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Dist.setValue(l); +} + +void TaskFemConstraintBearing::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +void TaskFemConstraintBearing::onButtonLocation(const bool pressed) { + if (pressed) { + selectionMode = selloc; + } else { + selectionMode = selnone; + } + ui->buttonLocation->setChecked(pressed); + Gui::Selection().clearSelection(); +} + +void TaskFemConstraintBearing::onCheckAxial(const bool pressed) +{ + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->AxialFree.setValue(pressed); +} + +double TaskFemConstraintBearing::getDistance(void) const +{ + return ui->spinDistance->value(); +} + +const std::string TaskFemConstraintBearing::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +const std::string TaskFemConstraintBearing::getLocationName(void) const +{ + std::string loc = ui->lineLocation->text().toStdString(); + if (loc.empty()) + return ""; + + int pos = loc.find_last_of(":"); + return loc.substr(0, pos).c_str(); +} + +const std::string TaskFemConstraintBearing::getLocationObject(void) const +{ + std::string loc = ui->lineLocation->text().toStdString(); + if (loc.empty()) + return ""; + + int pos = loc.find_last_of(":"); + return loc.substr(pos+1).c_str(); +} + +bool TaskFemConstraintBearing::getAxial() const +{ + return ui->checkAxial->isChecked(); +} + +TaskFemConstraintBearing::~TaskFemConstraintBearing() +{ + delete ui; +} + +void TaskFemConstraintBearing::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinDistance->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinDistance->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintBearing::TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintBearing(ConstraintView); + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintBearing::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintBearing* parameterBearing = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Dist = %f",name.c_str(), parameterBearing->getDistance()); + + std::string locname = parameterBearing->getLocationName().data(); + std::string locobj = parameterBearing->getLocationObject().data(); + + if (!locname.empty()) { + QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); + buf = buf.arg(QString::fromStdString(locname)); + buf = buf.arg(QString::fromStdString(locobj)); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = %s", name.c_str(), buf.toStdString().c_str()); + } else { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = None", name.c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.AxialFree = %s", name.c_str(), parameterBearing->getAxial() ? "True" : "False"); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return TaskDlgFemConstraint::accept(); +} + +#include "moc_TaskFemConstraintBearing.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintBearing.h b/src/Mod/Fem/Gui/TaskFemConstraintBearing.h index 466a1e8346b4..2d159939d2ff 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintBearing.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintBearing.h @@ -1,92 +1,92 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraintBearing_H -#define GUI_TASKVIEW_TaskFemConstraintBearing_H - -#include -#include -#include - -#include "TaskFemConstraint.h" -#include "ViewProviderFemConstraintBearing.h" - -class Ui_TaskFemConstraintBearing; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace FemGui { - -class TaskFemConstraintBearing : public TaskFemConstraint -{ - Q_OBJECT - -public: - TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView, QWidget *parent = 0, - const char* pixmapname = "fem-constraint-bearing"); - virtual ~TaskFemConstraintBearing(); - - double getDistance(void) const; - virtual const std::string getReferences() const; - const std::string getLocationName(void) const; - const std::string getLocationObject(void) const; - bool getAxial(void) const; - -private Q_SLOTS: - void onReferenceDeleted(void); - void onDistanceChanged(double l); - void onButtonLocation(const bool pressed = true); - void onCheckAxial(bool); - -protected: - virtual void changeEvent(QEvent *e); - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - -protected: - Ui_TaskFemConstraintBearing* ui; - -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraintBearing : public TaskDlgFemConstraint -{ - Q_OBJECT - -public: - TaskDlgFemConstraintBearing() {} - TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraintBearing_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintBearing_H +#define GUI_TASKVIEW_TaskFemConstraintBearing_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintBearing.h" + +class Ui_TaskFemConstraintBearing; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintBearing : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView, QWidget *parent = 0, + const char* pixmapname = "fem-constraint-bearing"); + virtual ~TaskFemConstraintBearing(); + + double getDistance(void) const; + virtual const std::string getReferences() const; + const std::string getLocationName(void) const; + const std::string getLocationObject(void) const; + bool getAxial(void) const; + +private Q_SLOTS: + void onReferenceDeleted(void); + void onDistanceChanged(double l); + void onButtonLocation(const bool pressed = true); + void onCheckAxial(bool); + +protected: + virtual void changeEvent(QEvent *e); + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + +protected: + Ui_TaskFemConstraintBearing* ui; + +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintBearing : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintBearing() {} + TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintBearing_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp index e367660ba90f..1fa025485fd1 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp @@ -1,236 +1,236 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskFemConstraintFixed.h" -#include "TaskFemConstraintFixed.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraintFixed */ - -TaskFemConstraintFixed::TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent) - : TaskFemConstraint(ConstraintView, parent, "fem-constraint-fixed") -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskFemConstraintFixed(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - // Create a context menu for the listview of the references - QAction* action = new QAction(tr("Delete"), ui->listReferences); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onReferenceDeleted())); - ui->listReferences->addAction(action); - ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->buttonReference, SIGNAL(pressed()), - this, SLOT(onButtonReference())); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->listReferences->blockSignals(true); - ui->buttonReference->blockSignals(true); - - // Get the feature data - Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - // Fill data into dialog elements - ui->listReferences->clear(); - for (std::size_t i = 0; i < Objects.size(); i++) - ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); - if (Objects.size() > 0) - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - - ui->listReferences->blockSignals(false); - ui->buttonReference->blockSignals(false); - - // Selection mode can be always on since there is nothing else in the UI - onButtonReference(true); -} - -void TaskFemConstraintFixed::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - std::vector references(1,subName); - Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == selref) { - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - // Ensure we don't have mixed reference types - if (SubElements.size() > 0) { - if (subName.substr(0,4) != SubElements.front().substr(0,4)) { - QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); - return; - } - } else { - if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); - return; - } - } - - // Avoid duplicates - std::size_t pos = 0; - for (; pos < Objects.size(); pos++) { - if (obj == Objects[pos]) { - break; - } - } - - if (pos != Objects.size()) { - if (subName == SubElements[pos]) { - return; - } - } - - // add the new reference - Objects.push_back(obj); - SubElements.push_back(subName); - pcConstraint->References.setValues(Objects,SubElements); - ui->listReferences->addItem(makeRefText(obj, subName)); - } - - Gui::Selection().clearSelection(); - } -} - -void TaskFemConstraintFixed::onReferenceDeleted() { - int row = ui->listReferences->currentIndex().row(); - TaskFemConstraint::onReferenceDeleted(row); - ui->listReferences->model()->removeRow(row); - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); -} - -const std::string TaskFemConstraintFixed::getReferences() const -{ - int rows = ui->listReferences->model()->rowCount(); - - std::vector items; - for (int r = 0; r < rows; r++) - items.push_back(ui->listReferences->item(r)->text().toStdString()); - return TaskFemConstraint::getReferences(items); -} - -TaskFemConstraintFixed::~TaskFemConstraintFixed() -{ - delete ui; -} - -void TaskFemConstraintFixed::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgFemConstraintFixed::TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView) -{ - this->ConstraintView = ConstraintView; - assert(ConstraintView); - this->parameter = new TaskFemConstraintFixed(ConstraintView);; - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -void TaskDlgFemConstraintFixed::open() -{ - // a transaction is already open at creation time of the panel - if (!Gui::Command::hasPendingCommand()) { - QString msg = QObject::tr("Constraint fixed"); - Gui::Command::openCommand((const char*)msg.toUtf8()); - ConstraintView->setVisible(true); - Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts - } -} - -bool TaskDlgFemConstraintFixed::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintFixed* parameterFixed = static_cast(parameter); - std::string scale = parameterFixed->getScale(); //OvG: determine modified scale - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale - return TaskDlgFemConstraint::accept(); -} - -#include "moc_TaskFemConstraintFixed.cpp" +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintFixed.h" +#include "TaskFemConstraintFixed.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintFixed */ + +TaskFemConstraintFixed::TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent) + : TaskFemConstraint(ConstraintView, parent, "fem-constraint-fixed") +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintFixed(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + + // Get the feature data + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Fill data into dialog elements + ui->listReferences->clear(); + for (std::size_t i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + + // Selection mode can be always on since there is nothing else in the UI + onButtonReference(true); +} + +void TaskFemConstraintFixed::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Ensure we don't have mixed reference types + if (SubElements.size() > 0) { + if (subName.substr(0,4) != SubElements.front().substr(0,4)) { + QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); + return; + } + } else { + if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); + return; + } + } + + // Avoid duplicates + std::size_t pos = 0; + for (; pos < Objects.size(); pos++) { + if (obj == Objects[pos]) { + break; + } + } + + if (pos != Objects.size()) { + if (subName == SubElements[pos]) { + return; + } + } + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + } + + Gui::Selection().clearSelection(); + } +} + +void TaskFemConstraintFixed::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +const std::string TaskFemConstraintFixed::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +TaskFemConstraintFixed::~TaskFemConstraintFixed() +{ + delete ui; +} + +void TaskFemConstraintFixed::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintFixed::TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintFixed(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +void TaskDlgFemConstraintFixed::open() +{ + // a transaction is already open at creation time of the panel + if (!Gui::Command::hasPendingCommand()) { + QString msg = QObject::tr("Constraint fixed"); + Gui::Command::openCommand((const char*)msg.toUtf8()); + ConstraintView->setVisible(true); + Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts + } +} + +bool TaskDlgFemConstraintFixed::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintFixed* parameterFixed = static_cast(parameter); + std::string scale = parameterFixed->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale + return TaskDlgFemConstraint::accept(); +} + +#include "moc_TaskFemConstraintFixed.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.h b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h index 08b93b1b3520..c4ebcf92c401 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h @@ -1,84 +1,84 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraintFixed_H -#define GUI_TASKVIEW_TaskFemConstraintFixed_H - -#include -#include -#include - -#include "TaskFemConstraint.h" -#include "ViewProviderFemConstraintFixed.h" - -class Ui_TaskFemConstraintFixed; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace FemGui { - -class TaskFemConstraintFixed : public TaskFemConstraint -{ - Q_OBJECT - -public: - TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent = 0); - virtual ~TaskFemConstraintFixed(); - - virtual const std::string getReferences() const; - -private Q_SLOTS: - void onReferenceDeleted(void); - -protected: - virtual void changeEvent(QEvent *e); - -private: - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - -private: - Ui_TaskFemConstraintFixed* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraintFixed : public TaskDlgFemConstraint -{ - Q_OBJECT - -public: - TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - void open(); -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraintFixed_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintFixed_H +#define GUI_TASKVIEW_TaskFemConstraintFixed_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintFixed.h" + +class Ui_TaskFemConstraintFixed; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintFixed : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent = 0); + virtual ~TaskFemConstraintFixed(); + + virtual const std::string getReferences() const; + +private Q_SLOTS: + void onReferenceDeleted(void); + +protected: + virtual void changeEvent(QEvent *e); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + +private: + Ui_TaskFemConstraintFixed* ui; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintFixed : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + void open(); +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintFixed_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp index b95d36e34d05..1643f7a507f0 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp @@ -1,403 +1,403 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskFemConstraintForce.h" -#include "TaskFemConstraintForce.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraintForce */ - -TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent) - : TaskFemConstraint(ConstraintView, parent, "fem-constraint-force") -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskFemConstraintForce(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - // Create a context menu for the listview of the references - QAction* action = new QAction(tr("Delete"), ui->listReferences); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onReferenceDeleted())); - ui->listReferences->addAction(action); - ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->spinForce, SIGNAL(valueChanged(double)), - this, SLOT(onForceChanged(double))); - connect(ui->buttonReference, SIGNAL(pressed()), - this, SLOT(onButtonReference())); - connect(ui->buttonDirection, SIGNAL(pressed()), - this, SLOT(onButtonDirection())); - connect(ui->checkReverse, SIGNAL(toggled(bool)), - this, SLOT(onCheckReverse(bool))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->spinForce->blockSignals(true); - ui->listReferences->blockSignals(true); - ui->buttonReference->blockSignals(true); - ui->buttonDirection->blockSignals(true); - ui->checkReverse->blockSignals(true); - - // Get the feature data - Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - double f = pcConstraint->Force.getValue(); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - std::vector dirStrings = pcConstraint->Direction.getSubValues(); - QString dir; - if (!dirStrings.empty()) - dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); - bool reversed = pcConstraint->Reversed.getValue(); - - // Fill data into dialog elements - ui->spinForce->setMinimum(0); - ui->spinForce->setMaximum(FLOAT_MAX); - ui->spinForce->setValue(f); - ui->listReferences->clear(); - for (std::size_t i = 0; i < Objects.size(); i++) - ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); - if (Objects.size() > 0) - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir); - ui->checkReverse->setChecked(reversed); - - ui->spinForce->blockSignals(false); - ui->listReferences->blockSignals(false); - ui->buttonReference->blockSignals(false); - ui->buttonDirection->blockSignals(false); - ui->checkReverse->blockSignals(false); - - updateUI(); -} - -void TaskFemConstraintForce::updateUI() -{ - if (ui->listReferences->model()->rowCount() == 0) { - // Go into reference selection mode if no reference has been selected yet - onButtonReference(true); - return; - } - - std::string ref = ui->listReferences->item(0)->text().toStdString(); - int pos = ref.find_last_of(":"); - if (ref.substr(pos+1, 6) == "Vertex") - ui->labelForce->setText(tr("Point load")); - else if (ref.substr(pos+1, 4) == "Edge") - ui->labelForce->setText(tr("Line load")); - else if (ref.substr(pos+1, 4) == "Face") - ui->labelForce->setText(tr("Area load")); -} - -void TaskFemConstraintForce::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - std::vector references(1,subName); - Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == selref) { - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - // Ensure we don't have mixed reference types - if (SubElements.size() > 0) { - if (subName.substr(0,4) != SubElements.front().substr(0,4)) { - QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); - return; - } - } - else { - if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); - return; - } - } - - // Avoid duplicates - std::size_t pos = 0; - for (; pos < Objects.size(); pos++) { - if (obj == Objects[pos]) { - break; - } - } - - if (pos != Objects.size()) { - if (subName == SubElements[pos]) { - return; - } - } - - // add the new reference - Objects.push_back(obj); - SubElements.push_back(subName); - pcConstraint->References.setValues(Objects,SubElements); - ui->listReferences->addItem(makeRefText(obj, subName)); - - // Turn off reference selection mode - onButtonReference(false); - } - else if (selectionMode == seldir) { - if (subName.substr(0,4) == "Face") { - if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); - return; - } - } - else if (subName.substr(0,4) == "Edge") { - if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); - return; - } - } - else { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); - return; - } - pcConstraint->Direction.setValue(obj, references); - ui->lineDirection->setText(makeRefText(obj, subName)); - - // Turn off direction selection mode - onButtonDirection(false); - } - - Gui::Selection().clearSelection(); - updateUI(); - } -} - -void TaskFemConstraintForce::onForceChanged(double f) -{ - Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Force.setValue(f); -} - -void TaskFemConstraintForce::onReferenceDeleted() { - int row = ui->listReferences->currentIndex().row(); - TaskFemConstraint::onReferenceDeleted(row); - ui->listReferences->model()->removeRow(row); - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); -} - -void TaskFemConstraintForce::onButtonDirection(const bool pressed) { - if (pressed) { - selectionMode = seldir; - } else { - selectionMode = selnone; - } - ui->buttonDirection->setChecked(pressed); - Gui::Selection().clearSelection(); -} - -void TaskFemConstraintForce::onCheckReverse(const bool pressed) -{ - Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Reversed.setValue(pressed); -} - -double TaskFemConstraintForce::getForce(void) const -{ - return ui->spinForce->value(); -} - -const std::string TaskFemConstraintForce::getReferences() const -{ - int rows = ui->listReferences->model()->rowCount(); - - std::vector items; - for (int r = 0; r < rows; r++) - items.push_back(ui->listReferences->item(r)->text().toStdString()); - return TaskFemConstraint::getReferences(items); -} - -const std::string TaskFemConstraintForce::getDirectionName(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(0, pos).c_str(); -} - -const std::string TaskFemConstraintForce::getDirectionObject(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(pos+1).c_str(); -} - -bool TaskFemConstraintForce::getReverse() const -{ - return ui->checkReverse->isChecked(); -} - -TaskFemConstraintForce::~TaskFemConstraintForce() -{ - delete ui; -} - -void TaskFemConstraintForce::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->spinForce->blockSignals(true); - ui->retranslateUi(proxy); - ui->spinForce->blockSignals(false); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgFemConstraintForce::TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView) -{ - this->ConstraintView = ConstraintView; - assert(ConstraintView); - this->parameter = new TaskFemConstraintForce(ConstraintView);; - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -void TaskDlgFemConstraintForce::open() -{ - // a transaction is already open at creation time of the panel - if (!Gui::Command::hasPendingCommand()) { - QString msg = QObject::tr("Constraint force"); - Gui::Command::openCommand((const char*)msg.toUtf8()); - ConstraintView->setVisible(true); - Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts - } -} - -bool TaskDlgFemConstraintForce::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintForce* parameterForce = static_cast(parameter); - - try { - //Gui::Command::openCommand("FEM force constraint changed"); - - if (parameterForce->getForce()<=0) - { - QMessageBox::warning(parameter, tr("Input error"), tr("Please specify a force greater than 0")); - return false; - } - else - { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterForce->getForce()); - } - std::string dirname = parameterForce->getDirectionName().data(); - std::string dirobj = parameterForce->getDirectionObject().data(); - std::string scale = "1"; - - if (!dirname.empty()) { - QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromStdString(dirname)); - buf = buf.arg(QString::fromStdString(dirobj)); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterForce->getReverse() ? "True" : "False"); - - scale = parameterForce->getScale(); //OvG: determine modified scale - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return TaskDlgFemConstraint::accept(); -} - -bool TaskDlgFemConstraintForce::reject() -{ - // roll back the changes - Gui::Command::abortCommand(); - Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); - Gui::Command::updateActive(); - - return true; -} - -#include "moc_TaskFemConstraintForce.cpp" +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintForce.h" +#include "TaskFemConstraintForce.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintForce */ + +TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent) + : TaskFemConstraint(ConstraintView, parent, "fem-constraint-force") +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintForce(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->spinForce, SIGNAL(valueChanged(double)), + this, SLOT(onForceChanged(double))); + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + connect(ui->buttonDirection, SIGNAL(pressed()), + this, SLOT(onButtonDirection())); + connect(ui->checkReverse, SIGNAL(toggled(bool)), + this, SLOT(onCheckReverse(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->spinForce->blockSignals(true); + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + ui->buttonDirection->blockSignals(true); + ui->checkReverse->blockSignals(true); + + // Get the feature data + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + double f = pcConstraint->Force.getValue(); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector dirStrings = pcConstraint->Direction.getSubValues(); + QString dir; + if (!dirStrings.empty()) + dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); + bool reversed = pcConstraint->Reversed.getValue(); + + // Fill data into dialog elements + ui->spinForce->setMinimum(0); + ui->spinForce->setMaximum(FLOAT_MAX); + ui->spinForce->setValue(f); + ui->listReferences->clear(); + for (std::size_t i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir); + ui->checkReverse->setChecked(reversed); + + ui->spinForce->blockSignals(false); + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + ui->buttonDirection->blockSignals(false); + ui->checkReverse->blockSignals(false); + + updateUI(); +} + +void TaskFemConstraintForce::updateUI() +{ + if (ui->listReferences->model()->rowCount() == 0) { + // Go into reference selection mode if no reference has been selected yet + onButtonReference(true); + return; + } + + std::string ref = ui->listReferences->item(0)->text().toStdString(); + int pos = ref.find_last_of(":"); + if (ref.substr(pos+1, 6) == "Vertex") + ui->labelForce->setText(tr("Point load")); + else if (ref.substr(pos+1, 4) == "Edge") + ui->labelForce->setText(tr("Line load")); + else if (ref.substr(pos+1, 4) == "Face") + ui->labelForce->setText(tr("Area load")); +} + +void TaskFemConstraintForce::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Ensure we don't have mixed reference types + if (SubElements.size() > 0) { + if (subName.substr(0,4) != SubElements.front().substr(0,4)) { + QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); + return; + } + } + else { + if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); + return; + } + } + + // Avoid duplicates + std::size_t pos = 0; + for (; pos < Objects.size(); pos++) { + if (obj == Objects[pos]) { + break; + } + } + + if (pos != Objects.size()) { + if (subName == SubElements[pos]) { + return; + } + } + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + + // Turn off reference selection mode + onButtonReference(false); + } + else if (selectionMode == seldir) { + if (subName.substr(0,4) == "Face") { + if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); + return; + } + } + else if (subName.substr(0,4) == "Edge") { + if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); + return; + } + } + else { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); + return; + } + pcConstraint->Direction.setValue(obj, references); + ui->lineDirection->setText(makeRefText(obj, subName)); + + // Turn off direction selection mode + onButtonDirection(false); + } + + Gui::Selection().clearSelection(); + updateUI(); + } +} + +void TaskFemConstraintForce::onForceChanged(double f) +{ + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Force.setValue(f); +} + +void TaskFemConstraintForce::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +void TaskFemConstraintForce::onButtonDirection(const bool pressed) { + if (pressed) { + selectionMode = seldir; + } else { + selectionMode = selnone; + } + ui->buttonDirection->setChecked(pressed); + Gui::Selection().clearSelection(); +} + +void TaskFemConstraintForce::onCheckReverse(const bool pressed) +{ + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Reversed.setValue(pressed); +} + +double TaskFemConstraintForce::getForce(void) const +{ + return ui->spinForce->value(); +} + +const std::string TaskFemConstraintForce::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +const std::string TaskFemConstraintForce::getDirectionName(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(0, pos).c_str(); +} + +const std::string TaskFemConstraintForce::getDirectionObject(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(pos+1).c_str(); +} + +bool TaskFemConstraintForce::getReverse() const +{ + return ui->checkReverse->isChecked(); +} + +TaskFemConstraintForce::~TaskFemConstraintForce() +{ + delete ui; +} + +void TaskFemConstraintForce::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinForce->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinForce->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintForce::TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintForce(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +void TaskDlgFemConstraintForce::open() +{ + // a transaction is already open at creation time of the panel + if (!Gui::Command::hasPendingCommand()) { + QString msg = QObject::tr("Constraint force"); + Gui::Command::openCommand((const char*)msg.toUtf8()); + ConstraintView->setVisible(true); + Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts + } +} + +bool TaskDlgFemConstraintForce::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintForce* parameterForce = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + + if (parameterForce->getForce()<=0) + { + QMessageBox::warning(parameter, tr("Input error"), tr("Please specify a force greater than 0")); + return false; + } + else + { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterForce->getForce()); + } + std::string dirname = parameterForce->getDirectionName().data(); + std::string dirobj = parameterForce->getDirectionObject().data(); + std::string scale = "1"; + + if (!dirname.empty()) { + QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); + buf = buf.arg(QString::fromStdString(dirname)); + buf = buf.arg(QString::fromStdString(dirobj)); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); + } else { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterForce->getReverse() ? "True" : "False"); + + scale = parameterForce->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return TaskDlgFemConstraint::accept(); +} + +bool TaskDlgFemConstraintForce::reject() +{ + // roll back the changes + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::updateActive(); + + return true; +} + +#include "moc_TaskFemConstraintForce.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.h b/src/Mod/Fem/Gui/TaskFemConstraintForce.h index c49b3afbdfca..34004b6b7a85 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintForce.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.h @@ -1,94 +1,94 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraintForce_H -#define GUI_TASKVIEW_TaskFemConstraintForce_H - -#include -#include -#include - -#include "TaskFemConstraint.h" -#include "ViewProviderFemConstraintForce.h" - -class Ui_TaskFemConstraintForce; - -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - -namespace FemGui { - -class TaskFemConstraintForce : public TaskFemConstraint -{ - Q_OBJECT - -public: - TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent = 0); - virtual ~TaskFemConstraintForce(); - - double getForce(void) const; - virtual const std::string getReferences() const; - const std::string getDirectionName(void) const; - const std::string getDirectionObject(void) const; - bool getReverse(void) const; - -private Q_SLOTS: - void onReferenceDeleted(void); - void onForceChanged(double); - void onButtonDirection(const bool pressed = true); - void onCheckReverse(bool); - -protected: - virtual void changeEvent(QEvent *e); - -private: - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); - void updateUI(); - -private: - Ui_TaskFemConstraintForce* ui; -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraintForce : public TaskDlgFemConstraint -{ - Q_OBJECT - -public: - TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual void open(); - virtual bool accept(); - virtual bool reject(); - -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraintForce_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintForce_H +#define GUI_TASKVIEW_TaskFemConstraintForce_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintForce.h" + +class Ui_TaskFemConstraintForce; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintForce : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent = 0); + virtual ~TaskFemConstraintForce(); + + double getForce(void) const; + virtual const std::string getReferences() const; + const std::string getDirectionName(void) const; + const std::string getDirectionObject(void) const; + bool getReverse(void) const; + +private Q_SLOTS: + void onReferenceDeleted(void); + void onForceChanged(double); + void onButtonDirection(const bool pressed = true); + void onCheckReverse(bool); + +protected: + virtual void changeEvent(QEvent *e); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); + +private: + Ui_TaskFemConstraintForce* ui; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintForce : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual void open(); + virtual bool accept(); + virtual bool reject(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintForce_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp b/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp index 3909f6c4cf7a..27cc8d687d9b 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp @@ -1,317 +1,317 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include */ -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ui_TaskFemConstraintBearing.h" -#include "TaskFemConstraintGear.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraintGear */ - -TaskFemConstraintGear::TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent, const char *pixmapname) - : TaskFemConstraintBearing(ConstraintView, parent, pixmapname) -{ - connect(ui->spinDiameter, SIGNAL(valueChanged(double)), - this, SLOT(onDiameterChanged(double))); - connect(ui->spinForce, SIGNAL(valueChanged(double)), - this, SLOT(onForceChanged(double))); - connect(ui->spinForceAngle, SIGNAL(valueChanged(double)), - this, SLOT(onForceAngleChanged(double))); - connect(ui->buttonDirection, SIGNAL(pressed()), - this, SLOT(onButtonDirection())); - connect(ui->checkReversed, SIGNAL(toggled(bool)), - this, SLOT(onCheckReversed(bool))); - - // Temporarily prevent unnecessary feature recomputes - ui->spinDiameter->blockSignals(true); - ui->spinForce->blockSignals(true); - ui->spinForceAngle->blockSignals(true); - ui->checkReversed->blockSignals(true); - - // Get the feature data - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - double dia = pcConstraint->Diameter.getValue(); - double force = pcConstraint->Force.getValue(); - double angle = pcConstraint->ForceAngle.getValue(); - std::vector dirStrings = pcConstraint->Direction.getSubValues(); - QString dir; - if (!dirStrings.empty()) - dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); - bool reversed = pcConstraint->Reversed.getValue(); - - // Fill data into dialog elements - ui->spinDiameter->setMinimum(0); - ui->spinDiameter->setMaximum(FLOAT_MAX); - ui->spinDiameter->setValue(dia); - ui->spinForce->setMinimum(0); - ui->spinForce->setMaximum(FLOAT_MAX); - ui->spinForce->setValue(force); - ui->spinForceAngle->setMinimum(-360); - ui->spinForceAngle->setMaximum(360); - ui->spinForceAngle->setValue(angle); - ui->lineDirection->setText(dir); - ui->checkReversed->setChecked(reversed); - - // Adjust ui - ui->labelDiameter->setVisible(true); - ui->spinDiameter->setVisible(true); - ui->labelForce->setVisible(true); - ui->spinForce->setVisible(true); - ui->labelForceAngle->setVisible(true); - ui->spinForceAngle->setVisible(true); - ui->buttonDirection->setVisible(true); - ui->lineDirection->setVisible(true); - ui->checkReversed->setVisible(true); - ui->checkAxial->setVisible(false); - - ui->spinDiameter->blockSignals(false); - ui->spinForce->blockSignals(false); - ui->spinForceAngle->blockSignals(false); - ui->checkReversed->blockSignals(false); -} - -void TaskFemConstraintGear::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - TaskFemConstraintBearing::onSelectionChanged(msg); - - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - std::vector references(1,subName); - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == seldir) { - if (subName.substr(0,4) == "Face") { - if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); - return; - } - } - else if (subName.substr(0,4) == "Edge") { - if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { - QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); - return; - } - } - else { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); - return; - } - pcConstraint->Direction.setValue(obj, references); - ui->lineDirection->setText(makeRefText(obj, subName)); - - // Turn off direction selection mode - onButtonDirection(false); - } - - Gui::Selection().clearSelection(); - } -} - -void TaskFemConstraintGear::onDiameterChanged(double l) -{ - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Diameter.setValue(l); -} - -void TaskFemConstraintGear::onForceChanged(double f) -{ - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Force.setValue(f); -} - -void TaskFemConstraintGear::onForceAngleChanged(double a) -{ - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->ForceAngle.setValue(a); -} - -void TaskFemConstraintGear::onButtonDirection(const bool pressed) { - if (pressed) { - selectionMode = seldir; - } else { - selectionMode = selnone; - } - ui->buttonDirection->setChecked(pressed); - Gui::Selection().clearSelection(); -} - -void TaskFemConstraintGear::onCheckReversed(const bool pressed) -{ - Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Reversed.setValue(pressed); -} - -double TaskFemConstraintGear::getForce(void) const -{ - return ui->spinForce->value(); -} - -double TaskFemConstraintGear::getForceAngle(void) const -{ - return ui->spinForceAngle->value(); -} - -const std::string TaskFemConstraintGear::getDirectionName(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(0, pos).c_str(); -} - -const std::string TaskFemConstraintGear::getDirectionObject(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(pos+1).c_str(); -} - -bool TaskFemConstraintGear::getReverse() const -{ - return ui->checkReversed->isChecked(); -} - -double TaskFemConstraintGear::getDiameter(void) const -{ - return ui->spinDiameter->value(); -} - -void TaskFemConstraintGear::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->spinDiameter->blockSignals(true); - ui->spinForce->blockSignals(true); - ui->spinForceAngle->blockSignals(true); - ui->checkReversed->blockSignals(true); - ui->retranslateUi(proxy); - ui->spinDiameter->blockSignals(false); - ui->spinForce->blockSignals(false); - ui->spinForceAngle->blockSignals(true); - ui->checkReversed->blockSignals(false); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgFemConstraintGear::TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView) -{ - this->ConstraintView = ConstraintView; - assert(ConstraintView); +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include */ +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintBearing.h" +#include "TaskFemConstraintGear.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintGear */ + +TaskFemConstraintGear::TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent, const char *pixmapname) + : TaskFemConstraintBearing(ConstraintView, parent, pixmapname) +{ + connect(ui->spinDiameter, SIGNAL(valueChanged(double)), + this, SLOT(onDiameterChanged(double))); + connect(ui->spinForce, SIGNAL(valueChanged(double)), + this, SLOT(onForceChanged(double))); + connect(ui->spinForceAngle, SIGNAL(valueChanged(double)), + this, SLOT(onForceAngleChanged(double))); + connect(ui->buttonDirection, SIGNAL(pressed()), + this, SLOT(onButtonDirection())); + connect(ui->checkReversed, SIGNAL(toggled(bool)), + this, SLOT(onCheckReversed(bool))); + + // Temporarily prevent unnecessary feature recomputes + ui->spinDiameter->blockSignals(true); + ui->spinForce->blockSignals(true); + ui->spinForceAngle->blockSignals(true); + ui->checkReversed->blockSignals(true); + + // Get the feature data + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + double dia = pcConstraint->Diameter.getValue(); + double force = pcConstraint->Force.getValue(); + double angle = pcConstraint->ForceAngle.getValue(); + std::vector dirStrings = pcConstraint->Direction.getSubValues(); + QString dir; + if (!dirStrings.empty()) + dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); + bool reversed = pcConstraint->Reversed.getValue(); + + // Fill data into dialog elements + ui->spinDiameter->setMinimum(0); + ui->spinDiameter->setMaximum(FLOAT_MAX); + ui->spinDiameter->setValue(dia); + ui->spinForce->setMinimum(0); + ui->spinForce->setMaximum(FLOAT_MAX); + ui->spinForce->setValue(force); + ui->spinForceAngle->setMinimum(-360); + ui->spinForceAngle->setMaximum(360); + ui->spinForceAngle->setValue(angle); + ui->lineDirection->setText(dir); + ui->checkReversed->setChecked(reversed); + + // Adjust ui + ui->labelDiameter->setVisible(true); + ui->spinDiameter->setVisible(true); + ui->labelForce->setVisible(true); + ui->spinForce->setVisible(true); + ui->labelForceAngle->setVisible(true); + ui->spinForceAngle->setVisible(true); + ui->buttonDirection->setVisible(true); + ui->lineDirection->setVisible(true); + ui->checkReversed->setVisible(true); + ui->checkAxial->setVisible(false); + + ui->spinDiameter->blockSignals(false); + ui->spinForce->blockSignals(false); + ui->spinForceAngle->blockSignals(false); + ui->checkReversed->blockSignals(false); +} + +void TaskFemConstraintGear::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + TaskFemConstraintBearing::onSelectionChanged(msg); + + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == seldir) { + if (subName.substr(0,4) == "Face") { + if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); + return; + } + } + else if (subName.substr(0,4) == "Edge") { + if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { + QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); + return; + } + } + else { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); + return; + } + pcConstraint->Direction.setValue(obj, references); + ui->lineDirection->setText(makeRefText(obj, subName)); + + // Turn off direction selection mode + onButtonDirection(false); + } + + Gui::Selection().clearSelection(); + } +} + +void TaskFemConstraintGear::onDiameterChanged(double l) +{ + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Diameter.setValue(l); +} + +void TaskFemConstraintGear::onForceChanged(double f) +{ + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Force.setValue(f); +} + +void TaskFemConstraintGear::onForceAngleChanged(double a) +{ + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->ForceAngle.setValue(a); +} + +void TaskFemConstraintGear::onButtonDirection(const bool pressed) { + if (pressed) { + selectionMode = seldir; + } else { + selectionMode = selnone; + } + ui->buttonDirection->setChecked(pressed); + Gui::Selection().clearSelection(); +} + +void TaskFemConstraintGear::onCheckReversed(const bool pressed) +{ + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Reversed.setValue(pressed); +} + +double TaskFemConstraintGear::getForce(void) const +{ + return ui->spinForce->value(); +} + +double TaskFemConstraintGear::getForceAngle(void) const +{ + return ui->spinForceAngle->value(); +} + +const std::string TaskFemConstraintGear::getDirectionName(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(0, pos).c_str(); +} + +const std::string TaskFemConstraintGear::getDirectionObject(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(pos+1).c_str(); +} + +bool TaskFemConstraintGear::getReverse() const +{ + return ui->checkReversed->isChecked(); +} + +double TaskFemConstraintGear::getDiameter(void) const +{ + return ui->spinDiameter->value(); +} + +void TaskFemConstraintGear::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinDiameter->blockSignals(true); + ui->spinForce->blockSignals(true); + ui->spinForceAngle->blockSignals(true); + ui->checkReversed->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinDiameter->blockSignals(false); + ui->spinForce->blockSignals(false); + ui->spinForceAngle->blockSignals(true); + ui->checkReversed->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintGear::TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); this->parameter = new TaskFemConstraintGear(ConstraintView, 0, "fem-constraint-gear"); - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -bool TaskDlgFemConstraintGear::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintGear* parameterGear = static_cast(parameter); - - try { - //Gui::Command::openCommand("FEM force constraint changed"); - std::string dirname = parameterGear->getDirectionName().data(); - std::string dirobj = parameterGear->getDirectionObject().data(); - - if (!dirname.empty()) { - QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromStdString(dirname)); - buf = buf.arg(QString::fromStdString(dirobj)); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterGear->getReverse() ? "True" : "False"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterGear->getDiameter()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterGear->getForce()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ForceAngle = %f",name.c_str(), parameterGear->getForceAngle()); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return TaskDlgFemConstraintBearing::accept(); -} - -#include "moc_TaskFemConstraintGear.cpp" + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintGear::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintGear* parameterGear = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + std::string dirname = parameterGear->getDirectionName().data(); + std::string dirobj = parameterGear->getDirectionObject().data(); + + if (!dirname.empty()) { + QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); + buf = buf.arg(QString::fromStdString(dirname)); + buf = buf.arg(QString::fromStdString(dirobj)); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); + } else { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterGear->getReverse() ? "True" : "False"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterGear->getDiameter()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterGear->getForce()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ForceAngle = %f",name.c_str(), parameterGear->getForceAngle()); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return TaskDlgFemConstraintBearing::accept(); +} + +#include "moc_TaskFemConstraintGear.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintGear.h b/src/Mod/Fem/Gui/TaskFemConstraintGear.h index f8af2abc472b..e8039cb7bb7d 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintGear.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintGear.h @@ -1,79 +1,79 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraintGear_H -#define GUI_TASKVIEW_TaskFemConstraintGear_H - -#include -#include -#include - -#include "TaskFemConstraintBearing.h" -#include "ViewProviderFemConstraintGear.h" - -namespace FemGui { - -class TaskFemConstraintGear : public TaskFemConstraintBearing -{ - Q_OBJECT - -public: - TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0, - const char* pixmapname = "fem-constraint-gear"); - - double getDiameter(void) const; - double getForce(void) const; - double getForceAngle(void) const; - const std::string getDirectionName(void) const; - const std::string getDirectionObject(void) const; - bool getReverse(void) const; - -private Q_SLOTS: - void onDiameterChanged(double dia); - void onForceChanged(double force); - void onForceAngleChanged(double angle); - void onButtonDirection(const bool pressed = true); - void onCheckReversed(bool); - -protected: - virtual void changeEvent(QEvent *e); - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraintGear : public TaskDlgFemConstraintBearing -{ - Q_OBJECT - -public: - TaskDlgFemConstraintGear() {} - TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraintGear_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintGear_H +#define GUI_TASKVIEW_TaskFemConstraintGear_H + +#include +#include +#include + +#include "TaskFemConstraintBearing.h" +#include "ViewProviderFemConstraintGear.h" + +namespace FemGui { + +class TaskFemConstraintGear : public TaskFemConstraintBearing +{ + Q_OBJECT + +public: + TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0, + const char* pixmapname = "fem-constraint-gear"); + + double getDiameter(void) const; + double getForce(void) const; + double getForceAngle(void) const; + const std::string getDirectionName(void) const; + const std::string getDirectionObject(void) const; + bool getReverse(void) const; + +private Q_SLOTS: + void onDiameterChanged(double dia); + void onForceChanged(double force); + void onForceAngleChanged(double angle); + void onButtonDirection(const bool pressed = true); + void onCheckReversed(bool); + +protected: + virtual void changeEvent(QEvent *e); + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintGear : public TaskDlgFemConstraintBearing +{ + Q_OBJECT + +public: + TaskDlgFemConstraintGear() {} + TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintGear_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp b/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp index 5a84ac364741..564594036df8 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp @@ -1,222 +1,222 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -#endif - -#include "ui_TaskFemConstraintBearing.h" -#include "TaskFemConstraintPulley.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace FemGui; -using namespace Gui; - -/* TRANSLATOR FemGui::TaskFemConstraintPulley */ - -TaskFemConstraintPulley::TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent) +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +#endif + +#include "ui_TaskFemConstraintBearing.h" +#include "TaskFemConstraintPulley.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintPulley */ + +TaskFemConstraintPulley::TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent) : TaskFemConstraintGear(ConstraintView, parent, "fem-constraint-pulley") -{ - connect(ui->spinOtherDiameter, SIGNAL(valueChanged(double)), - this, SLOT(onOtherDiameterChanged(double))); - connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)), - this, SLOT(onCenterDistanceChanged(double))); - connect(ui->checkIsDriven, SIGNAL(toggled(bool)), - this, SLOT(onCheckIsDriven(bool))); - connect(ui->spinTensionForce, SIGNAL(valueChanged(double)), - this, SLOT(onTensionForceChanged(double))); - - // Temporarily prevent unnecessary feature recomputes - ui->spinOtherDiameter->blockSignals(true); - ui->spinCenterDistance->blockSignals(true); - ui->checkIsDriven->blockSignals(true); - ui->spinTensionForce->blockSignals(true); - - // Get the feature data - Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); - double otherdia = pcConstraint->OtherDiameter.getValue(); - double centerdist = pcConstraint->CenterDistance.getValue(); - bool isdriven = pcConstraint->IsDriven.getValue(); - double tensionforce = pcConstraint->TensionForce.getValue(); - - // Fill data into dialog elements - ui->spinOtherDiameter->setMinimum(0); - ui->spinOtherDiameter->setMaximum(FLOAT_MAX); - ui->spinOtherDiameter->setValue(otherdia); - ui->spinCenterDistance->setMinimum(0); - ui->spinCenterDistance->setMaximum(FLOAT_MAX); - ui->spinCenterDistance->setValue(centerdist); - ui->checkIsDriven->setChecked(isdriven); - ui->spinForce->setMinimum(-FLOAT_MAX); - ui->spinTensionForce->setMinimum(0); - ui->spinTensionForce->setMaximum(FLOAT_MAX); - ui->spinTensionForce->setValue(tensionforce); - - // Adjust ui - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReversed->setVisible(false); - ui->labelDiameter->setText(tr("Pulley diameter")); - ui->labelForce->setText(tr("Torque [Nm]")); - ui->labelOtherDiameter->setVisible(true); - ui->spinOtherDiameter->setVisible(true); - ui->labelCenterDistance->setVisible(true); - ui->spinCenterDistance->setVisible(true); - ui->checkIsDriven->setVisible(true); - ui->labelTensionForce->setVisible(true); - ui->spinTensionForce->setVisible(true); - - ui->spinOtherDiameter->blockSignals(false); - ui->spinCenterDistance->blockSignals(false); - ui->checkIsDriven->blockSignals(false); - ui->spinTensionForce->blockSignals(false); -} - -void TaskFemConstraintPulley::onOtherDiameterChanged(double l) -{ - Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->OtherDiameter.setValue(l); -} - -void TaskFemConstraintPulley::onCenterDistanceChanged(double l) -{ - Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->CenterDistance.setValue(l); -} - -void TaskFemConstraintPulley::onTensionForceChanged(double force) -{ - Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->TensionForce.setValue(force); -} - -void TaskFemConstraintPulley::onCheckIsDriven(const bool pressed) -{ - Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->IsDriven.setValue(pressed); -} - -double TaskFemConstraintPulley::getTorque(void) const -{ - return ui->spinForce->value(); -} - -double TaskFemConstraintPulley::getTensionForce(void) const -{ - return ui->spinTensionForce->value(); -} - -bool TaskFemConstraintPulley::getIsDriven() const -{ - return ui->checkIsDriven->isChecked(); -} - -double TaskFemConstraintPulley::getOtherDiameter(void) const -{ - return ui->spinOtherDiameter->value(); -} - -double TaskFemConstraintPulley::getCenterDistance(void) const -{ - return ui->spinCenterDistance->value(); -} - -void TaskFemConstraintPulley::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->spinOtherDiameter->blockSignals(true); - ui->spinCenterDistance->blockSignals(true); - ui->checkIsDriven->blockSignals(true); - ui->spinTensionForce->blockSignals(true); - ui->retranslateUi(proxy); - ui->spinOtherDiameter->blockSignals(false); - ui->spinCenterDistance->blockSignals(false); - ui->checkIsDriven->blockSignals(false); - ui->spinTensionForce->blockSignals(false); - } -} - -//************************************************************************** -//************************************************************************** -// TaskDialog -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -TaskDlgFemConstraintPulley::TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView) -{ - this->ConstraintView = ConstraintView; - assert(ConstraintView); - this->parameter = new TaskFemConstraintPulley(ConstraintView);; - - Content.push_back(parameter); -} - -//==== calls from the TaskView =============================================================== - -void TaskDlgFemConstraintPulley::open() -{ - // a transaction is already open at creation time of the panel - if (!Gui::Command::hasPendingCommand()) { - QString msg = QObject::tr("Constraint pulley"); - Gui::Command::openCommand((const char*)msg.toUtf8()); - ConstraintView->setVisible(true); - Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts - } -} - -bool TaskDlgFemConstraintPulley::accept() -{ - std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintPulley* parameterPulley = static_cast(parameter); - - try { - //Gui::Command::openCommand("FEM pulley constraint changed"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(), parameterPulley->getOtherDiameter()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(), parameterPulley->getCenterDistance()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.IsDriven = %s",name.c_str(), parameterPulley->getIsDriven() ? "True" : "False"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TensionForce = %f",name.c_str(), parameterPulley->getTensionForce()); - } - catch (const Base::Exception& e) { - QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); - return false; - } - - return TaskDlgFemConstraintGear::accept(); -} - -#include "moc_TaskFemConstraintPulley.cpp" +{ + connect(ui->spinOtherDiameter, SIGNAL(valueChanged(double)), + this, SLOT(onOtherDiameterChanged(double))); + connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)), + this, SLOT(onCenterDistanceChanged(double))); + connect(ui->checkIsDriven, SIGNAL(toggled(bool)), + this, SLOT(onCheckIsDriven(bool))); + connect(ui->spinTensionForce, SIGNAL(valueChanged(double)), + this, SLOT(onTensionForceChanged(double))); + + // Temporarily prevent unnecessary feature recomputes + ui->spinOtherDiameter->blockSignals(true); + ui->spinCenterDistance->blockSignals(true); + ui->checkIsDriven->blockSignals(true); + ui->spinTensionForce->blockSignals(true); + + // Get the feature data + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + double otherdia = pcConstraint->OtherDiameter.getValue(); + double centerdist = pcConstraint->CenterDistance.getValue(); + bool isdriven = pcConstraint->IsDriven.getValue(); + double tensionforce = pcConstraint->TensionForce.getValue(); + + // Fill data into dialog elements + ui->spinOtherDiameter->setMinimum(0); + ui->spinOtherDiameter->setMaximum(FLOAT_MAX); + ui->spinOtherDiameter->setValue(otherdia); + ui->spinCenterDistance->setMinimum(0); + ui->spinCenterDistance->setMaximum(FLOAT_MAX); + ui->spinCenterDistance->setValue(centerdist); + ui->checkIsDriven->setChecked(isdriven); + ui->spinForce->setMinimum(-FLOAT_MAX); + ui->spinTensionForce->setMinimum(0); + ui->spinTensionForce->setMaximum(FLOAT_MAX); + ui->spinTensionForce->setValue(tensionforce); + + // Adjust ui + ui->buttonDirection->setVisible(false); + ui->lineDirection->setVisible(false); + ui->checkReversed->setVisible(false); + ui->labelDiameter->setText(tr("Pulley diameter")); + ui->labelForce->setText(tr("Torque [Nm]")); + ui->labelOtherDiameter->setVisible(true); + ui->spinOtherDiameter->setVisible(true); + ui->labelCenterDistance->setVisible(true); + ui->spinCenterDistance->setVisible(true); + ui->checkIsDriven->setVisible(true); + ui->labelTensionForce->setVisible(true); + ui->spinTensionForce->setVisible(true); + + ui->spinOtherDiameter->blockSignals(false); + ui->spinCenterDistance->blockSignals(false); + ui->checkIsDriven->blockSignals(false); + ui->spinTensionForce->blockSignals(false); +} + +void TaskFemConstraintPulley::onOtherDiameterChanged(double l) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->OtherDiameter.setValue(l); +} + +void TaskFemConstraintPulley::onCenterDistanceChanged(double l) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->CenterDistance.setValue(l); +} + +void TaskFemConstraintPulley::onTensionForceChanged(double force) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->TensionForce.setValue(force); +} + +void TaskFemConstraintPulley::onCheckIsDriven(const bool pressed) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->IsDriven.setValue(pressed); +} + +double TaskFemConstraintPulley::getTorque(void) const +{ + return ui->spinForce->value(); +} + +double TaskFemConstraintPulley::getTensionForce(void) const +{ + return ui->spinTensionForce->value(); +} + +bool TaskFemConstraintPulley::getIsDriven() const +{ + return ui->checkIsDriven->isChecked(); +} + +double TaskFemConstraintPulley::getOtherDiameter(void) const +{ + return ui->spinOtherDiameter->value(); +} + +double TaskFemConstraintPulley::getCenterDistance(void) const +{ + return ui->spinCenterDistance->value(); +} + +void TaskFemConstraintPulley::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinOtherDiameter->blockSignals(true); + ui->spinCenterDistance->blockSignals(true); + ui->checkIsDriven->blockSignals(true); + ui->spinTensionForce->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinOtherDiameter->blockSignals(false); + ui->spinCenterDistance->blockSignals(false); + ui->checkIsDriven->blockSignals(false); + ui->spinTensionForce->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintPulley::TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintPulley(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +void TaskDlgFemConstraintPulley::open() +{ + // a transaction is already open at creation time of the panel + if (!Gui::Command::hasPendingCommand()) { + QString msg = QObject::tr("Constraint pulley"); + Gui::Command::openCommand((const char*)msg.toUtf8()); + ConstraintView->setVisible(true); + Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts + } +} + +bool TaskDlgFemConstraintPulley::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintPulley* parameterPulley = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM pulley constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(), parameterPulley->getOtherDiameter()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(), parameterPulley->getCenterDistance()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.IsDriven = %s",name.c_str(), parameterPulley->getIsDriven() ? "True" : "False"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TensionForce = %f",name.c_str(), parameterPulley->getTensionForce()); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return TaskDlgFemConstraintGear::accept(); +} + +#include "moc_TaskFemConstraintPulley.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintPulley.h b/src/Mod/Fem/Gui/TaskFemConstraintPulley.h index 5ec4916cea62..2160c5bed7d2 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintPulley.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintPulley.h @@ -1,74 +1,74 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_TASKVIEW_TaskFemConstraintPulley_H -#define GUI_TASKVIEW_TaskFemConstraintPulley_H - -#include -#include -#include - -#include "TaskFemConstraintGear.h" -#include "ViewProviderFemConstraintPulley.h" - -namespace FemGui { - -class TaskFemConstraintPulley : public TaskFemConstraintGear -{ - Q_OBJECT - -public: - TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent = 0); - - double getOtherDiameter(void) const; - double getCenterDistance(void) const; - double getTensionForce(void) const; - double getTorque(void) const; - bool getIsDriven(void) const; - -private Q_SLOTS: - void onOtherDiameterChanged(double dia); - void onCenterDistanceChanged(double dia); - void onTensionForceChanged(double force); - void onCheckIsDriven(bool); - -protected: - virtual void changeEvent(QEvent *e); -}; - -/// simulation dialog for the TaskView -class TaskDlgFemConstraintPulley : public TaskDlgFemConstraintGear -{ - Q_OBJECT - -public: - TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); - void open(); -}; - -} //namespace FemGui - -#endif // GUI_TASKVIEW_TaskFemConstraintPulley_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintPulley_H +#define GUI_TASKVIEW_TaskFemConstraintPulley_H + +#include +#include +#include + +#include "TaskFemConstraintGear.h" +#include "ViewProviderFemConstraintPulley.h" + +namespace FemGui { + +class TaskFemConstraintPulley : public TaskFemConstraintGear +{ + Q_OBJECT + +public: + TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent = 0); + + double getOtherDiameter(void) const; + double getCenterDistance(void) const; + double getTensionForce(void) const; + double getTorque(void) const; + bool getIsDriven(void) const; + +private Q_SLOTS: + void onOtherDiameterChanged(double dia); + void onCenterDistanceChanged(double dia); + void onTensionForceChanged(double force); + void onCheckIsDriven(bool); + +protected: + virtual void changeEvent(QEvent *e); +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintPulley : public TaskDlgFemConstraintGear +{ + Q_OBJECT + +public: + TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + void open(); +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintPulley_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp index 6042d868ae47..0bdff0d0542a 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp @@ -1,496 +1,496 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraint.h" -#include "TaskFemConstraint.h" - -#include "Gui/Control.h" -#include "Gui/MainWindow.h" -#include "Gui/Command.h" -#include "Gui/Application.h" -#include "Gui/Document.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraint, Gui::ViewProviderDocumentObject) - - -ViewProviderFemConstraint::ViewProviderFemConstraint() -{ - ADD_PROPERTY(TextColor,(0.0f,0.0f,0.0f)); - ADD_PROPERTY(FaceColor,(1.0f,0.0f,0.2f)); - ADD_PROPERTY(ShapeColor,(1.0f,0.0f,0.2f)); - ADD_PROPERTY(FontSize,(18)); - ADD_PROPERTY(DistFactor,(1.0)); - ADD_PROPERTY(Mirror,(false)); - - pFont = new SoFontStyle(); - pFont->ref(); - pLabel = new SoText2(); - pLabel->ref(); - pTextColor = new SoBaseColor(); - pTextColor->ref(); - - pMaterials = new SoBaseColor(); - pMaterials->ref(); - pMaterials->rgb.setValue(1.0f, 0.0f, 0.2f); - - pShapeSep = new SoSeparator(); - pShapeSep->ref(); - - TextColor.touch(); - FontSize.touch(); - FaceColor.touch(); - - wizardWidget = NULL; - wizardSubLayout = NULL; - constraintDialog = NULL; -} - -ViewProviderFemConstraint::~ViewProviderFemConstraint() -{ - pFont->unref(); - pLabel->unref(); - pTextColor->unref(); - pMaterials->unref(); - pShapeSep->unref(); -} - -void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) -{ - ViewProviderDocumentObject::attach(pcObject); - - SoPickStyle* ps = new SoPickStyle(); - ps->style = SoPickStyle::UNPICKABLE; - - SoSeparator* sep = new SoSeparator(); - SoShapeHints* hints = new SoShapeHints(); - hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); - hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE); - sep->addChild(ps); - sep->addChild(hints); - sep->addChild(pMaterials); - sep->addChild(pShapeSep); - addDisplayMaskMode(sep, "Base"); -} - -std::vector ViewProviderFemConstraint::getDisplayModes(void) const -{ - // add modes - std::vector StrList; - StrList.push_back("Base"); - return StrList; -} - -void ViewProviderFemConstraint::setDisplayMode(const char* ModeName) -{ - if (strcmp(ModeName, "Base") == 0) - setDisplayMaskMode("Base"); - ViewProviderDocumentObject::setDisplayMode(ModeName); -} - -std::vector ViewProviderFemConstraint::claimChildren(void)const -{ - return std::vector(); -} - -void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) -{ - QAction* act; - act = menu->addAction(QObject::tr("Edit constraint"), receiver, member); - act->setData(QVariant((int)ViewProvider::Default)); - ViewProviderDocumentObject::setupContextMenu(menu, receiver, member); -} - -void ViewProviderFemConstraint::onChanged(const App::Property* prop) -{ - if (prop == &Mirror || prop == &DistFactor) { - updateData(prop); - } - else if (prop == &TextColor) { - const App::Color& c = TextColor.getValue(); - pTextColor->rgb.setValue(c.r,c.g,c.b); - } - else if (prop == &FaceColor) { - const App::Color& c = FaceColor.getValue(); - pMaterials->rgb.setValue(c.r,c.g,c.b); - } - else if (prop == &FontSize) { - pFont->size = FontSize.getValue(); - } - else { - ViewProviderDocumentObject::onChanged(prop); - } -} - -//OvG: Visibility automation show parts and hide meshes on activation of a constraint -std::string ViewProviderFemConstraint::gethideMeshShowPartStr(const std::string showConstr) -{ - return "for amesh in App.activeDocument().Objects:\n\ - if \""+showConstr+"\" == amesh.Name:\n\ - amesh.ViewObject.Visibility = True\n\ - elif \"Mesh\" in amesh.TypeId:\n\ - aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ - for apart in App.activeDocument().Objects:\n\ - if aparttoshow == apart.Name:\n\ - apart.ViewObject.Visibility = True\n\ - amesh.ViewObject.Visibility = False\n"; -} - -std::string ViewProviderFemConstraint::gethideMeshShowPartStr() -{ - return ViewProviderFemConstraint::gethideMeshShowPartStr(""); -} - -bool ViewProviderFemConstraint::setEdit(int ModNum) -{ - Gui::Command::doCommand(Gui::Command::Doc,"%s",ViewProviderFemConstraint::gethideMeshShowPartStr().c_str()); - return Gui::ViewProviderGeometryObject::setEdit(ModNum); -} - -void ViewProviderFemConstraint::unsetEdit(int ModNum) -{ - if ((wizardWidget != NULL) && (wizardSubLayout != NULL) && (constraintDialog != NULL)) { - wizardWidget = NULL; - wizardSubLayout = NULL; - delete constraintDialog; - constraintDialog = NULL; - - // Notify the Shaft Wizard that we have finished editing - // See WizardShaft.py on why we do it this way - Gui::Command::runCommand(Gui::Command::Doc, "Gui.runCommand('PartDesign_WizardShaftCallBack')"); - } else { - if (ModNum == ViewProvider::Default) { - // when pressing ESC make sure to close the dialog - Gui::Control().closeDialog(); - } - else { - ViewProviderDocumentObject::unsetEdit(ModNum); - } - } -} -/* -// Create a local coordinate system with the z-axis given in dir -void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x) -{ - // Find the y axis in an arbitrary direction, normal to z - // Conditions: - // y1 * z1 + y2 * z2 + y3 * z3 = |y| |z| cos(90°) = 0 - // |y| = sqrt(y1^2 + y2^2 + y3^2) = 1 - float z1, z2, z3; - z.getValue(z1, z2, z3); - float y1, y2, y3; - if (fabs(z1) > Precision::Confusion()) { - // Choose: y3 = 0 - // Solution: - // y1 * z1 + y2 * z2 = 0 - // y1 = - z2/z1 y2 - // sqrt(z2^2/z1^2 y2^2 + y2^2) = 1 - // y2^2 ( 1 + z2^2/z1^2)) = +-1 -> choose +1 otherwise no solution - // y2 = +- sqrt(1 / (1 + z2^2/z1^2)) - y3 = 0; - y2 = sqrt(1 / (1 + z2*z2 / (z1*z1))); - y1 = -z2/z1 * y2; - // Note: result might be (0, 1, 0) - } else if (fabs(z2) > Precision::Confusion()) { - // Given: z1 = 0 - // Choose: y1 = 0 - // Solution: - // y2 * z2 + y3 * z3 = 0 - // y2 = - z3/z2 y3 - // sqrt(z3^2/z2^2 y3^3 + y3^2) = 1 - // y3^2 (1 + z3^2/z2^2)) = +1 - // y3 = +- sqrt(1 / (1 + z3^2/z2^2)) - y1 = 0; - y3 = sqrt(1 / (1 + z3*z3 / (z2*z2))); - y2 = -z3/z2 * y3; - // Note: result might be (0, 0, 1) - } else if (fabs(z3) > Precision::Confusion()) { - // Given: z1 = z2 = 0 - // Choose the remaining possible axis - y1 = 1; - y2 = 0; - y3 = 0; - } - - y = SbVec3f(y1, y2, y3); - x = y.cross(z); -} -*/ -#define PLACEMENT_CHILDREN 2 - -void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r) -{ - SoTranslation* trans = new SoTranslation(); - trans->translation.setValue(base); - sep->addChild(trans); - SoRotation* rot = new SoRotation(); - rot->rotation.setValue(r); - sep->addChild(rot); -} - -void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r) -{ - SoTranslation* trans = static_cast(sep->getChild(idx)); - trans->translation.setValue(base); - SoRotation* rot = static_cast(sep->getChild(idx+1)); - rot->rotation.setValue(r); -} - -#define CONE_CHILDREN 2 - -void ViewProviderFemConstraint::createCone(SoSeparator* sep, const double height, const double radius) -{ - // Adjust cone so that the tip is on base - SoTranslation* trans = new SoTranslation(); - trans->translation.setValue(SbVec3f(0,-height/2,0)); - sep->addChild(trans); - SoCone* cone = new SoCone(); - cone->height.setValue(height); - cone->bottomRadius.setValue(radius); - sep->addChild(cone); -} - -SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius) -{ - // Create a new cone node - SoSeparator* sep = new SoSeparator(); - createCone(sep, height, radius); - return sep; -} - -void ViewProviderFemConstraint::updateCone(const SoNode* node, const int idx, const double height, const double radius) -{ - const SoSeparator* sep = static_cast(node); - SoTranslation* trans = static_cast(sep->getChild(idx)); - trans->translation.setValue(SbVec3f(0,-height/2,0)); - SoCone* cone = static_cast(sep->getChild(idx+1)); - cone->height.setValue(height); - cone->bottomRadius.setValue(radius); -} - -#define CYLINDER_CHILDREN 1 - -void ViewProviderFemConstraint::createCylinder(SoSeparator* sep, const double height, const double radius) -{ - SoCylinder* cyl = new SoCylinder(); - cyl->height.setValue(height); - cyl->radius.setValue(radius); - sep->addChild(cyl); -} - -SoSeparator* ViewProviderFemConstraint::createCylinder(const double height, const double radius) -{ - // Create a new cylinder node - SoSeparator* sep = new SoSeparator(); - createCylinder(sep, height, radius); - return sep; -} - -void ViewProviderFemConstraint::updateCylinder(const SoNode* node, const int idx, const double height, const double radius) -{ - const SoSeparator* sep = static_cast(node); - SoCylinder* cyl = static_cast(sep->getChild(idx)); - cyl->height.setValue(height); - cyl->radius.setValue(radius); -} - -#define CUBE_CHILDREN 1 - -void ViewProviderFemConstraint::createCube(SoSeparator* sep, const double width, const double length, const double height) -{ - SoCube* cube = new SoCube(); - cube->width.setValue(width); - cube->depth.setValue(length); - cube->height.setValue(height); - sep->addChild(cube); -} - -SoSeparator* ViewProviderFemConstraint::createCube(const double width, const double length, const double height) -{ - SoSeparator* sep = new SoSeparator(); - createCube(sep, width, length, height); - return sep; -} - -void ViewProviderFemConstraint::updateCube(const SoNode* node, const int idx, const double width, const double length, const double height) -{ - const SoSeparator* sep = static_cast(node); - SoCube* cube = static_cast(sep->getChild(idx)); - cube->width.setValue(width); - cube->depth.setValue(length); - cube->height.setValue(height); -} - -#define ARROW_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN) - -void ViewProviderFemConstraint::createArrow(SoSeparator* sep, const double length, const double radius) -{ - createCone(sep, radius, radius/2); - createPlacement(sep, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); - createCylinder(sep, length-radius, radius/5); -} - -SoSeparator* ViewProviderFemConstraint::createArrow(const double length, const double radius) -{ - SoSeparator* sep = new SoSeparator(); - createArrow(sep, length, radius); - return sep; -} - -void ViewProviderFemConstraint::updateArrow(const SoNode* node, const int idx, const double length, const double radius) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, radius, radius/2); - updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); - updateCylinder(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, length-radius, radius/5); -} - -#define FIXED_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CUBE_CHILDREN) - -void ViewProviderFemConstraint::createFixed(SoSeparator* sep, const double height, const double width, const bool gap) -{ - createCone(sep, height-width/4, height-width/4); - createPlacement(sep, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); - createCube(sep, width, width, width/4); -} - -SoSeparator* ViewProviderFemConstraint::createFixed(const double height, const double width, const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createFixed(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, height-width/4, height-width/4); - updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); - updateCube(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, width, width, width/4); -} - -void ViewProviderFemConstraint::createDisplacement(SoSeparator* sep, const double height, const double width, const bool gap) -{ - createCone(sep, height, width); - createPlacement(sep, SbVec3f(0, -(height)/2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); -} - -SoSeparator* ViewProviderFemConstraint::createDisplacement(const double height, const double width, const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createDisplacement(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateDisplacement(const SoNode* node, const int idx, const double height, const double width, const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCone(sep, idx, height, width); - updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -(height)/2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); -} - -void ViewProviderFemConstraint::createRotation(SoSeparator* sep, const double height, const double width, const bool gap) -{ - createCylinder(sep, width/2, height/2); - createPlacement(sep, SbVec3f(0, -(height)*2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); -} - -SoSeparator* ViewProviderFemConstraint::createRotation(const double height, const double width, const bool gap) -{ - SoSeparator* sep = new SoSeparator(); - createRotation(sep, height, width, gap); - return sep; -} - -void ViewProviderFemConstraint::updateRotation(const SoNode* node, const int idx, const double height, const double width, const bool gap) -{ - const SoSeparator* sep = static_cast(node); - updateCylinder(sep, idx, height/2, width/2); - updatePlacement(sep, idx+CYLINDER_CHILDREN, SbVec3f(0, -(height)*2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); -} - -QObject* ViewProviderFemConstraint::findChildByName(const QObject* parent, const QString& name) -{ - for (QObjectList::const_iterator o = parent->children().begin(); o != parent->children().end(); o++) { - if ((*o)->objectName() == name) - return *o; - if (!(*o)->children().empty()) { - QObject* result = findChildByName(*o, name); - if (result != NULL) - return result; - } - } - - return NULL; -} - -void ViewProviderFemConstraint::checkForWizard() -{ - wizardWidget= NULL; - wizardSubLayout = NULL; - Gui::MainWindow* mw = Gui::getMainWindow(); - if (mw == NULL) return; - QDockWidget* dw = mw->findChild(QString::fromLatin1("Combo View")); - if (dw == NULL) return; - QWidget* cw = dw->findChild(QString::fromLatin1("Combo View")); - if (cw == NULL) return; - QTabWidget* tw = cw->findChild(QString::fromLatin1("combiTab")); - if (tw == NULL) return; - QStackedWidget* sw = tw->findChild(QString::fromLatin1("qt_tabwidget_stackedwidget")); - if (sw == NULL) return; - QScrollArea* sa = sw->findChild(); - if (sa== NULL) return; - QWidget* wd = sa->widget(); // This is the reason why we cannot use findChildByName() right away!!! - if (wd == NULL) return; - QObject* wiz = findChildByName(wd, QString::fromLatin1("ShaftWizard")); - if (wiz != NULL) { - wizardWidget = static_cast(wiz); - wizardSubLayout = wiz->findChild(QString::fromLatin1("ShaftWizardLayout")); - } -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraint.h" +#include "TaskFemConstraint.h" + +#include "Gui/Control.h" +#include "Gui/MainWindow.h" +#include "Gui/Command.h" +#include "Gui/Application.h" +#include "Gui/Document.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraint, Gui::ViewProviderDocumentObject) + + +ViewProviderFemConstraint::ViewProviderFemConstraint() +{ + ADD_PROPERTY(TextColor,(0.0f,0.0f,0.0f)); + ADD_PROPERTY(FaceColor,(1.0f,0.0f,0.2f)); + ADD_PROPERTY(ShapeColor,(1.0f,0.0f,0.2f)); + ADD_PROPERTY(FontSize,(18)); + ADD_PROPERTY(DistFactor,(1.0)); + ADD_PROPERTY(Mirror,(false)); + + pFont = new SoFontStyle(); + pFont->ref(); + pLabel = new SoText2(); + pLabel->ref(); + pTextColor = new SoBaseColor(); + pTextColor->ref(); + + pMaterials = new SoBaseColor(); + pMaterials->ref(); + pMaterials->rgb.setValue(1.0f, 0.0f, 0.2f); + + pShapeSep = new SoSeparator(); + pShapeSep->ref(); + + TextColor.touch(); + FontSize.touch(); + FaceColor.touch(); + + wizardWidget = NULL; + wizardSubLayout = NULL; + constraintDialog = NULL; +} + +ViewProviderFemConstraint::~ViewProviderFemConstraint() +{ + pFont->unref(); + pLabel->unref(); + pTextColor->unref(); + pMaterials->unref(); + pShapeSep->unref(); +} + +void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) +{ + ViewProviderDocumentObject::attach(pcObject); + + SoPickStyle* ps = new SoPickStyle(); + ps->style = SoPickStyle::UNPICKABLE; + + SoSeparator* sep = new SoSeparator(); + SoShapeHints* hints = new SoShapeHints(); + hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); + hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE); + sep->addChild(ps); + sep->addChild(hints); + sep->addChild(pMaterials); + sep->addChild(pShapeSep); + addDisplayMaskMode(sep, "Base"); +} + +std::vector ViewProviderFemConstraint::getDisplayModes(void) const +{ + // add modes + std::vector StrList; + StrList.push_back("Base"); + return StrList; +} + +void ViewProviderFemConstraint::setDisplayMode(const char* ModeName) +{ + if (strcmp(ModeName, "Base") == 0) + setDisplayMaskMode("Base"); + ViewProviderDocumentObject::setDisplayMode(ModeName); +} + +std::vector ViewProviderFemConstraint::claimChildren(void)const +{ + return std::vector(); +} + +void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) +{ + QAction* act; + act = menu->addAction(QObject::tr("Edit constraint"), receiver, member); + act->setData(QVariant((int)ViewProvider::Default)); + ViewProviderDocumentObject::setupContextMenu(menu, receiver, member); +} + +void ViewProviderFemConstraint::onChanged(const App::Property* prop) +{ + if (prop == &Mirror || prop == &DistFactor) { + updateData(prop); + } + else if (prop == &TextColor) { + const App::Color& c = TextColor.getValue(); + pTextColor->rgb.setValue(c.r,c.g,c.b); + } + else if (prop == &FaceColor) { + const App::Color& c = FaceColor.getValue(); + pMaterials->rgb.setValue(c.r,c.g,c.b); + } + else if (prop == &FontSize) { + pFont->size = FontSize.getValue(); + } + else { + ViewProviderDocumentObject::onChanged(prop); + } +} + +//OvG: Visibility automation show parts and hide meshes on activation of a constraint +std::string ViewProviderFemConstraint::gethideMeshShowPartStr(const std::string showConstr) +{ + return "for amesh in App.activeDocument().Objects:\n\ + if \""+showConstr+"\" == amesh.Name:\n\ + amesh.ViewObject.Visibility = True\n\ + elif \"Mesh\" in amesh.TypeId:\n\ + aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\ + for apart in App.activeDocument().Objects:\n\ + if aparttoshow == apart.Name:\n\ + apart.ViewObject.Visibility = True\n\ + amesh.ViewObject.Visibility = False\n"; +} + +std::string ViewProviderFemConstraint::gethideMeshShowPartStr() +{ + return ViewProviderFemConstraint::gethideMeshShowPartStr(""); +} + +bool ViewProviderFemConstraint::setEdit(int ModNum) +{ + Gui::Command::doCommand(Gui::Command::Doc,"%s",ViewProviderFemConstraint::gethideMeshShowPartStr().c_str()); + return Gui::ViewProviderGeometryObject::setEdit(ModNum); +} + +void ViewProviderFemConstraint::unsetEdit(int ModNum) +{ + if ((wizardWidget != NULL) && (wizardSubLayout != NULL) && (constraintDialog != NULL)) { + wizardWidget = NULL; + wizardSubLayout = NULL; + delete constraintDialog; + constraintDialog = NULL; + + // Notify the Shaft Wizard that we have finished editing + // See WizardShaft.py on why we do it this way + Gui::Command::runCommand(Gui::Command::Doc, "Gui.runCommand('PartDesign_WizardShaftCallBack')"); + } else { + if (ModNum == ViewProvider::Default) { + // when pressing ESC make sure to close the dialog + Gui::Control().closeDialog(); + } + else { + ViewProviderDocumentObject::unsetEdit(ModNum); + } + } +} +/* +// Create a local coordinate system with the z-axis given in dir +void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x) +{ + // Find the y axis in an arbitrary direction, normal to z + // Conditions: + // y1 * z1 + y2 * z2 + y3 * z3 = |y| |z| cos(90°) = 0 + // |y| = sqrt(y1^2 + y2^2 + y3^2) = 1 + float z1, z2, z3; + z.getValue(z1, z2, z3); + float y1, y2, y3; + if (fabs(z1) > Precision::Confusion()) { + // Choose: y3 = 0 + // Solution: + // y1 * z1 + y2 * z2 = 0 + // y1 = - z2/z1 y2 + // sqrt(z2^2/z1^2 y2^2 + y2^2) = 1 + // y2^2 ( 1 + z2^2/z1^2)) = +-1 -> choose +1 otherwise no solution + // y2 = +- sqrt(1 / (1 + z2^2/z1^2)) + y3 = 0; + y2 = sqrt(1 / (1 + z2*z2 / (z1*z1))); + y1 = -z2/z1 * y2; + // Note: result might be (0, 1, 0) + } else if (fabs(z2) > Precision::Confusion()) { + // Given: z1 = 0 + // Choose: y1 = 0 + // Solution: + // y2 * z2 + y3 * z3 = 0 + // y2 = - z3/z2 y3 + // sqrt(z3^2/z2^2 y3^3 + y3^2) = 1 + // y3^2 (1 + z3^2/z2^2)) = +1 + // y3 = +- sqrt(1 / (1 + z3^2/z2^2)) + y1 = 0; + y3 = sqrt(1 / (1 + z3*z3 / (z2*z2))); + y2 = -z3/z2 * y3; + // Note: result might be (0, 0, 1) + } else if (fabs(z3) > Precision::Confusion()) { + // Given: z1 = z2 = 0 + // Choose the remaining possible axis + y1 = 1; + y2 = 0; + y3 = 0; + } + + y = SbVec3f(y1, y2, y3); + x = y.cross(z); +} +*/ +#define PLACEMENT_CHILDREN 2 + +void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r) +{ + SoTranslation* trans = new SoTranslation(); + trans->translation.setValue(base); + sep->addChild(trans); + SoRotation* rot = new SoRotation(); + rot->rotation.setValue(r); + sep->addChild(rot); +} + +void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r) +{ + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(base); + SoRotation* rot = static_cast(sep->getChild(idx+1)); + rot->rotation.setValue(r); +} + +#define CONE_CHILDREN 2 + +void ViewProviderFemConstraint::createCone(SoSeparator* sep, const double height, const double radius) +{ + // Adjust cone so that the tip is on base + SoTranslation* trans = new SoTranslation(); + trans->translation.setValue(SbVec3f(0,-height/2,0)); + sep->addChild(trans); + SoCone* cone = new SoCone(); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); + sep->addChild(cone); +} + +SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius) +{ + // Create a new cone node + SoSeparator* sep = new SoSeparator(); + createCone(sep, height, radius); + return sep; +} + +void ViewProviderFemConstraint::updateCone(const SoNode* node, const int idx, const double height, const double radius) +{ + const SoSeparator* sep = static_cast(node); + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(SbVec3f(0,-height/2,0)); + SoCone* cone = static_cast(sep->getChild(idx+1)); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); +} + +#define CYLINDER_CHILDREN 1 + +void ViewProviderFemConstraint::createCylinder(SoSeparator* sep, const double height, const double radius) +{ + SoCylinder* cyl = new SoCylinder(); + cyl->height.setValue(height); + cyl->radius.setValue(radius); + sep->addChild(cyl); +} + +SoSeparator* ViewProviderFemConstraint::createCylinder(const double height, const double radius) +{ + // Create a new cylinder node + SoSeparator* sep = new SoSeparator(); + createCylinder(sep, height, radius); + return sep; +} + +void ViewProviderFemConstraint::updateCylinder(const SoNode* node, const int idx, const double height, const double radius) +{ + const SoSeparator* sep = static_cast(node); + SoCylinder* cyl = static_cast(sep->getChild(idx)); + cyl->height.setValue(height); + cyl->radius.setValue(radius); +} + +#define CUBE_CHILDREN 1 + +void ViewProviderFemConstraint::createCube(SoSeparator* sep, const double width, const double length, const double height) +{ + SoCube* cube = new SoCube(); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); + sep->addChild(cube); +} + +SoSeparator* ViewProviderFemConstraint::createCube(const double width, const double length, const double height) +{ + SoSeparator* sep = new SoSeparator(); + createCube(sep, width, length, height); + return sep; +} + +void ViewProviderFemConstraint::updateCube(const SoNode* node, const int idx, const double width, const double length, const double height) +{ + const SoSeparator* sep = static_cast(node); + SoCube* cube = static_cast(sep->getChild(idx)); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); +} + +#define ARROW_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN) + +void ViewProviderFemConstraint::createArrow(SoSeparator* sep, const double length, const double radius) +{ + createCone(sep, radius, radius/2); + createPlacement(sep, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); + createCylinder(sep, length-radius, radius/5); +} + +SoSeparator* ViewProviderFemConstraint::createArrow(const double length, const double radius) +{ + SoSeparator* sep = new SoSeparator(); + createArrow(sep, length, radius); + return sep; +} + +void ViewProviderFemConstraint::updateArrow(const SoNode* node, const int idx, const double length, const double radius) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, radius, radius/2); + updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); + updateCylinder(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, length-radius, radius/5); +} + +#define FIXED_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CUBE_CHILDREN) + +void ViewProviderFemConstraint::createFixed(SoSeparator* sep, const double height, const double width, const bool gap) +{ + createCone(sep, height-width/4, height-width/4); + createPlacement(sep, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); + createCube(sep, width, width, width/4); +} + +SoSeparator* ViewProviderFemConstraint::createFixed(const double height, const double width, const bool gap) +{ + SoSeparator* sep = new SoSeparator(); + createFixed(sep, height, width, gap); + return sep; +} + +void ViewProviderFemConstraint::updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, height-width/4, height-width/4); + updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); + updateCube(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, width, width, width/4); +} + +void ViewProviderFemConstraint::createDisplacement(SoSeparator* sep, const double height, const double width, const bool gap) +{ + createCone(sep, height, width); + createPlacement(sep, SbVec3f(0, -(height)/2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); +} + +SoSeparator* ViewProviderFemConstraint::createDisplacement(const double height, const double width, const bool gap) +{ + SoSeparator* sep = new SoSeparator(); + createDisplacement(sep, height, width, gap); + return sep; +} + +void ViewProviderFemConstraint::updateDisplacement(const SoNode* node, const int idx, const double height, const double width, const bool gap) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, height, width); + updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -(height)/2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); +} + +void ViewProviderFemConstraint::createRotation(SoSeparator* sep, const double height, const double width, const bool gap) +{ + createCylinder(sep, width/2, height/2); + createPlacement(sep, SbVec3f(0, -(height)*2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); +} + +SoSeparator* ViewProviderFemConstraint::createRotation(const double height, const double width, const bool gap) +{ + SoSeparator* sep = new SoSeparator(); + createRotation(sep, height, width, gap); + return sep; +} + +void ViewProviderFemConstraint::updateRotation(const SoNode* node, const int idx, const double height, const double width, const bool gap) +{ + const SoSeparator* sep = static_cast(node); + updateCylinder(sep, idx, height/2, width/2); + updatePlacement(sep, idx+CYLINDER_CHILDREN, SbVec3f(0, -(height)*2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); +} + +QObject* ViewProviderFemConstraint::findChildByName(const QObject* parent, const QString& name) +{ + for (QObjectList::const_iterator o = parent->children().begin(); o != parent->children().end(); o++) { + if ((*o)->objectName() == name) + return *o; + if (!(*o)->children().empty()) { + QObject* result = findChildByName(*o, name); + if (result != NULL) + return result; + } + } + + return NULL; +} + +void ViewProviderFemConstraint::checkForWizard() +{ + wizardWidget= NULL; + wizardSubLayout = NULL; + Gui::MainWindow* mw = Gui::getMainWindow(); + if (mw == NULL) return; + QDockWidget* dw = mw->findChild(QString::fromLatin1("Combo View")); + if (dw == NULL) return; + QWidget* cw = dw->findChild(QString::fromLatin1("Combo View")); + if (cw == NULL) return; + QTabWidget* tw = cw->findChild(QString::fromLatin1("combiTab")); + if (tw == NULL) return; + QStackedWidget* sw = tw->findChild(QString::fromLatin1("qt_tabwidget_stackedwidget")); + if (sw == NULL) return; + QScrollArea* sa = sw->findChild(); + if (sa== NULL) return; + QWidget* wd = sa->widget(); // This is the reason why we cannot use findChildByName() right away!!! + if (wd == NULL) return; + QObject* wiz = findChildByName(wd, QString::fromLatin1("ShaftWizard")); + if (wiz != NULL) { + wizardWidget = static_cast(wiz); + wizardSubLayout = wiz->findChild(QString::fromLatin1("ShaftWizardLayout")); + } +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h index 688597714557..14b905c9b786 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h @@ -1,123 +1,123 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINT_H -#define GUI_VIEWPROVIDERFEMCONSTRAINT_H - -#include -#include -#include - -class SoFontStyle; -class SoText2; -class SoBaseColor; -class SoTranslation; -class SbRotation; -class SoMaterial; - -namespace FemGui -{ - -class TaskFemConstraint; - -class FemGuiExport ViewProviderFemConstraint : public Gui::ViewProviderGeometryObject -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraint); - -public: - /// Constructor - ViewProviderFemConstraint(void); - virtual ~ViewProviderFemConstraint(); - - // Display properties - App::PropertyColor TextColor; - App::PropertyColor FaceColor; - App::PropertyColor ShapeColor; - App::PropertyInteger FontSize; - App::PropertyFloat DistFactor; - App::PropertyBool Mirror; - - void attach(App::DocumentObject *); - virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); } - std::vector getDisplayModes(void) const; - void setDisplayMode(const char* ModeName); - - std::vector claimChildren(void)const; - void setupContextMenu(QMenu*, QObject*, const char*); - - static std::string gethideMeshShowPartStr(); - static std::string gethideMeshShowPartStr(const std::string showConstr); - -protected: - void onChanged(const App::Property* prop); - virtual bool setEdit(int ModNum); - virtual void unsetEdit(int ModNum); - - static void createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r); - static void updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r); - static void createCone(SoSeparator* sep, const double height, const double radius); - static SoSeparator* createCone(const double height, const double radius); - static void updateCone(const SoNode* node, const int idx, const double height, const double radius); - static void createCylinder(SoSeparator* sep, const double height, const double radius); - static SoSeparator* createCylinder(const double height, const double radius); - static void updateCylinder(const SoNode* node, const int idx, const double height, const double radius); - static void createCube(SoSeparator* sep, const double width, const double length, const double height); - static SoSeparator* createCube(const double width, const double length, const double height); - static void updateCube(const SoNode* node, const int idx, const double width, const double length, const double height); - static void createArrow(SoSeparator* sep, const double length, const double radius); - static SoSeparator* createArrow(const double length, const double radius); - static void updateArrow(const SoNode* node, const int idx, const double length, const double radius); - static void createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false); - static SoSeparator* createFixed(const double height, const double width, const bool gap = false); - static void updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); - static void createDisplacement(SoSeparator* sep, const double height, const double width, const bool gap = false); - static SoSeparator* createDisplacement(const double height, const double width, const bool gap = false); - static void updateDisplacement(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); - static void createRotation(SoSeparator* sep, const double height, const double width, const bool gap = false); - static SoSeparator* createRotation(const double height, const double width, const bool gap = false); - static void updateRotation(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); - -private: - SoFontStyle * pFont; - SoText2 * pLabel; - SoBaseColor * pTextColor; - SoBaseColor * pMaterials; - -protected: - SoSeparator * pShapeSep; - - // Shaft design wizard integration -protected: - friend class TaskFemConstraint; - QVBoxLayout* wizardWidget; - QVBoxLayout* wizardSubLayout; - TaskFemConstraint* constraintDialog; - - void checkForWizard(); - static QObject* findChildByName(const QObject* parent, const QString& name); -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINT_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINT_H +#define GUI_VIEWPROVIDERFEMCONSTRAINT_H + +#include +#include +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; + +namespace FemGui +{ + +class TaskFemConstraint; + +class FemGuiExport ViewProviderFemConstraint : public Gui::ViewProviderGeometryObject +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraint); + +public: + /// Constructor + ViewProviderFemConstraint(void); + virtual ~ViewProviderFemConstraint(); + + // Display properties + App::PropertyColor TextColor; + App::PropertyColor FaceColor; + App::PropertyColor ShapeColor; + App::PropertyInteger FontSize; + App::PropertyFloat DistFactor; + App::PropertyBool Mirror; + + void attach(App::DocumentObject *); + virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); } + std::vector getDisplayModes(void) const; + void setDisplayMode(const char* ModeName); + + std::vector claimChildren(void)const; + void setupContextMenu(QMenu*, QObject*, const char*); + + static std::string gethideMeshShowPartStr(); + static std::string gethideMeshShowPartStr(const std::string showConstr); + +protected: + void onChanged(const App::Property* prop); + virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); + + static void createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r); + static void updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r); + static void createCone(SoSeparator* sep, const double height, const double radius); + static SoSeparator* createCone(const double height, const double radius); + static void updateCone(const SoNode* node, const int idx, const double height, const double radius); + static void createCylinder(SoSeparator* sep, const double height, const double radius); + static SoSeparator* createCylinder(const double height, const double radius); + static void updateCylinder(const SoNode* node, const int idx, const double height, const double radius); + static void createCube(SoSeparator* sep, const double width, const double length, const double height); + static SoSeparator* createCube(const double width, const double length, const double height); + static void updateCube(const SoNode* node, const int idx, const double width, const double length, const double height); + static void createArrow(SoSeparator* sep, const double length, const double radius); + static SoSeparator* createArrow(const double length, const double radius); + static void updateArrow(const SoNode* node, const int idx, const double length, const double radius); + static void createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false); + static SoSeparator* createFixed(const double height, const double width, const bool gap = false); + static void updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); + static void createDisplacement(SoSeparator* sep, const double height, const double width, const bool gap = false); + static SoSeparator* createDisplacement(const double height, const double width, const bool gap = false); + static void updateDisplacement(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); + static void createRotation(SoSeparator* sep, const double height, const double width, const bool gap = false); + static SoSeparator* createRotation(const double height, const double width, const bool gap = false); + static void updateRotation(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); + +private: + SoFontStyle * pFont; + SoText2 * pLabel; + SoBaseColor * pTextColor; + SoBaseColor * pMaterials; + +protected: + SoSeparator * pShapeSep; + + // Shaft design wizard integration +protected: + friend class TaskFemConstraint; + QVBoxLayout* wizardWidget; + QVBoxLayout* wizardSubLayout; + TaskFemConstraint* constraintDialog; + + void checkForWizard(); + static QObject* findChildByName(const QObject* parent, const QString& name); +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINT_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp index f869a65b1903..aea648d5af01 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp @@ -1,152 +1,152 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraintBearing.h" -#include -#include "TaskFemConstraintBearing.h" -#include "Gui/Control.h" -#include "Gui/MainWindow.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintBearing, FemGui::ViewProviderFemConstraint) - - -ViewProviderFemConstraintBearing::ViewProviderFemConstraintBearing() -{ - sPixmap = "fem-constraint-bearing"; -} - -ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing() -{ -} - -bool ViewProviderFemConstraintBearing::setEdit(int ModNum) -{ - - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraintBearing *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - // This case will occur in the ShaftWizard application - checkForWizard(); - if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { - // No shaft wizard is running - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } else if (constraintDialog != NULL) { - // Another FemConstraint* dialog is already open inside the Shaft Wizard - // Ignore the request to open another dialog - return false; - } else { - constraintDialog = new TaskFemConstraintBearing(this); - return true; - } - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraintBearing(this)); - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) -{ - // Gets called whenever a property of the attached object changes - Fem::ConstraintBearing* pcConstraint = static_cast(this->getObject()); - - if (strcmp(prop->getName(),"References") == 0) - Base::Console().Error("\n"); // enable a breakpoint here - - if (strcmp(prop->getName(),"BasePoint") == 0) { - // Remove and recreate the symbol - pShapeSep->removeAllChildren(); - - // This should always point outside of the cylinder - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - Base::Vector3d base = pcConstraint->BasePoint.getValue(); - double radius = pcConstraint->Radius.getValue(); - base = base + radius * normal; - - SbVec3f b(base.x, base.y, base.z); - SbVec3f dir(normal.x, normal.y, normal.z); - SbRotation rot(SbVec3f(0,-1,0), dir); - - createPlacement(pShapeSep, b, rot); - pShapeSep->addChild(createFixed(radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue())); - } else if (strcmp(prop->getName(),"AxialFree") == 0) { - if (pShapeSep->getNumChildren() > 0) { - // Change the symbol - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - Base::Vector3d base = pcConstraint->BasePoint.getValue(); - double radius = pcConstraint->Radius.getValue(); - base = base + radius * normal; - - SbVec3f b(base.x, base.y, base.z); - SbVec3f dir(normal.x, normal.y, normal.z); - SbRotation rot(SbVec3f(0,-1,0), dir); - - updatePlacement(pShapeSep, 0, b, rot); - const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateFixed(sep, 0, radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue()); - } - } - - ViewProviderFemConstraint::updateData(prop); -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintBearing.h" +#include +#include "TaskFemConstraintBearing.h" +#include "Gui/Control.h" +#include "Gui/MainWindow.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintBearing, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintBearing::ViewProviderFemConstraintBearing() +{ + sPixmap = "fem-constraint-bearing"; +} + +ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing() +{ +} + +bool ViewProviderFemConstraintBearing::setEdit(int ModNum) +{ + + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintBearing *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // This case will occur in the ShaftWizard application + checkForWizard(); + if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { + // No shaft wizard is running + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } else if (constraintDialog != NULL) { + // Another FemConstraint* dialog is already open inside the Shaft Wizard + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintBearing(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintBearing(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintBearing* pcConstraint = static_cast(this->getObject()); + + if (strcmp(prop->getName(),"References") == 0) + Base::Console().Error("\n"); // enable a breakpoint here + + if (strcmp(prop->getName(),"BasePoint") == 0) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + // This should always point outside of the cylinder + Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3d base = pcConstraint->BasePoint.getValue(); + double radius = pcConstraint->Radius.getValue(); + base = base + radius * normal; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(normal.x, normal.y, normal.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + createPlacement(pShapeSep, b, rot); + pShapeSep->addChild(createFixed(radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue())); + } else if (strcmp(prop->getName(),"AxialFree") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3d base = pcConstraint->BasePoint.getValue(); + double radius = pcConstraint->Radius.getValue(); + base = base + radius * normal; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(normal.x, normal.y, normal.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + updatePlacement(pShapeSep, 0, b, rot); + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateFixed(sep, 0, radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue()); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h index 675342d8343e..40e9eef19dda 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h @@ -1,50 +1,50 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H -#define GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H - -#include "ViewProviderFemConstraint.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemConstraintBearing : public FemGui::ViewProviderFemConstraint -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraintBearing); - -public: - /// Constructor - ViewProviderFemConstraintBearing(); - virtual ~ViewProviderFemConstraintBearing(); - - virtual void updateData(const App::Property*); - -protected: - virtual bool setEdit(int ModNum); -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintBearing : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintBearing); + +public: + /// Constructor + ViewProviderFemConstraintBearing(); + virtual ~ViewProviderFemConstraintBearing(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp index 4e5c701e6df6..98c9b12546bc 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp @@ -1,170 +1,170 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraintFixed.h" -#include -#include "TaskFemConstraintFixed.h" - -#include "Gui/Control.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemConstraint) - - -ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed() -{ - sPixmap = "fem-constraint-fixed"; -} - -ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed() -{ -} - -bool ViewProviderFemConstraintFixed::setEdit(int ModNum) -{ - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraintFixed *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - // This case will occur in the ShaftWizard application - checkForWizard(); - if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { - // No shaft wizard is running - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } else if (constraintDialog != NULL) { - // Another FemConstraint* dialog is already open inside the Shaft Wizard - // Ignore the request to open another dialog - return false; - } else { - constraintDialog = new TaskFemConstraintFixed(this); - return true; - } - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraintFixed(this)); - - return true; - } else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -#define WIDTH (2) -#define HEIGHT (1) -//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - so disable - -void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) -{ - // Gets called whenever a property of the attached object changes - Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); - float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only - float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); - -#ifdef USE_MULTIPLE_COPY - //OvG: always need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); //OvG: Scaling - pShapeSep->addChild(cp); - } -#endif - - if (strcmp(prop->getName(),"Points") == 0) { - const std::vector& points = pcConstraint->Points.getValues(); - const std::vector& normals = pcConstraint->Normals.getValues(); - if (points.size() != normals.size()) - return; - std::vector::const_iterator n = normals.begin(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Note: Points and Normals are always updated together - pShapeSep->removeAllChildren(); -#endif - - for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { - SbVec3f base(p->x, p->y, p->z); - SbVec3f dir(n->x, n->y, n->z); - SbRotation rot(SbVec3f(0,-1,0), dir); -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1,1,1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createFixed(sep, scaledheight, scaledwidth); //OvG: Scaling - pShapeSep->addChild(sep); -#endif - n++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - - ViewProviderFemConstraint::updateData(prop); -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintFixed.h" +#include +#include "TaskFemConstraintFixed.h" + +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed() +{ + sPixmap = "fem-constraint-fixed"; +} + +ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed() +{ +} + +bool ViewProviderFemConstraintFixed::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintFixed *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // This case will occur in the ShaftWizard application + checkForWizard(); + if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { + // No shaft wizard is running + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } else if (constraintDialog != NULL) { + // Another FemConstraint* dialog is already open inside the Shaft Wizard + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintFixed(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintFixed(this)); + + return true; + } else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +#define WIDTH (2) +#define HEIGHT (1) +//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing - so disable + +void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); + float scaledwidth = WIDTH * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledheight = HEIGHT * pcConstraint->Scale.getValue(); + +#ifdef USE_MULTIPLE_COPY + //OvG: always need access to cp for scaling + SoMultipleCopy* cp = new SoMultipleCopy(); + if (pShapeSep->getNumChildren() == 0) { + // Set up the nodes + cp->matrix.setNum(0); + cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); //OvG: Scaling + pShapeSep->addChild(cp); + } +#endif + + if (strcmp(prop->getName(),"Points") == 0) { + const std::vector& points = pcConstraint->Points.getValues(); + const std::vector& normals = pcConstraint->Normals.getValues(); + if (points.size() != normals.size()) + return; + std::vector::const_iterator n = normals.begin(); + +#ifdef USE_MULTIPLE_COPY + cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + SbMatrix* matrices = cp->matrix.startEditing(); + int idx = 0; +#else + // Note: Points and Normals are always updated together + pShapeSep->removeAllChildren(); +#endif + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + SbVec3f dir(n->x, n->y, n->z); + SbRotation rot(SbVec3f(0,-1,0), dir); +#ifdef USE_MULTIPLE_COPY + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + matrices[idx] = m; + idx++; +#else + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, base, rot); + createFixed(sep, scaledheight, scaledwidth); //OvG: Scaling + pShapeSep->addChild(sep); +#endif + n++; + } +#ifdef USE_MULTIPLE_COPY + cp->matrix.finishEditing(); +#endif + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h index f2f2863d3ad1..bc43553a596c 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h @@ -1,50 +1,50 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H -#define GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H - -#include "ViewProviderFemConstraint.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemConstraintFixed : public FemGui::ViewProviderFemConstraint -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraintFixed); - -public: - /// Constructor - ViewProviderFemConstraintFixed(); - virtual ~ViewProviderFemConstraintFixed(); - - virtual void updateData(const App::Property*); - -protected: - virtual bool setEdit(int ModNum); -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintFixed : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintFixed); + +public: + /// Constructor + ViewProviderFemConstraintFixed(); + virtual ~ViewProviderFemConstraintFixed(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp index 0a08e0640184..bff783435690 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp @@ -1,213 +1,213 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraintForce.h" -#include -#include "TaskFemConstraintForce.h" -#include "Gui/Control.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemConstraint) - - -ViewProviderFemConstraintForce::ViewProviderFemConstraintForce() -{ - sPixmap = "fem-constraint-force"; -} - -ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce() -{ -} - -bool ViewProviderFemConstraintForce::setEdit(int ModNum) -{ - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraintForce *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - // This case will occur in the ShaftWizard application - checkForWizard(); - if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { - // No shaft wizard is running - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } else if (constraintDialog != NULL) { - // Another FemConstraint* dialog is already open inside the Shaft Wizard - // Ignore the request to open another dialog - return false; - } else { - constraintDialog = new TaskFemConstraintForce(this); - return true; - } - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraintForce(this)); - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -#define ARROWLENGTH (4) -#define ARROWHEADRADIUS (ARROWLENGTH/3) -//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so disable - -void ViewProviderFemConstraintForce::updateData(const App::Property* prop) -{ - // Gets called whenever a property of the attached object changes - Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); - float scaledheadradius = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only - float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); - -#ifdef USE_MULTIPLE_COPY - //OvG: need access to cp for scaling - SoMultipleCopy* cp = new SoMultipleCopy(); - if (pShapeSep->getNumChildren() == 0) { - // Set up the nodes - cp->matrix.setNum(0); - cp->addChild((SoNode*)createArrow(scaledlength , scaledheadradius)); //OvG: Scaling - pShapeSep->addChild(cp); - } -#endif - - if (strcmp(prop->getName(),"Points") == 0) { - const std::vector& points = pcConstraint->Points.getValues(); - -#ifdef USE_MULTIPLE_COPY - cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); - int idx = 0; -#else - // Redraw all arrows - pShapeSep->removeAllChildren(); -#endif - // This should always point outside of the solid - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - - // Get default direction (on first call to method) - Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); - if (forceDirection.Length() < Precision::Confusion()) - forceDirection = normal; - - SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); - SbRotation rot(SbVec3f(0,1,0), dir); - - for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { - SbVec3f base(p->x, p->y, p->z); - if (forceDirection.GetAngle(normal) < M_PI_2) // Move arrow so it doesn't disappear inside the solid - base = base + dir * scaledlength; //OvG: Scaling -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1,1,1)); - matrices[idx] = m; - idx++; -#else - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, base, rot); - createArrow(sep, scaledlength, scaledheadradius); //OvG: Scaling - pShapeSep->addChild(sep); -#endif - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - else if (strcmp(prop->getName(),"DirectionVector") == 0) { // Note: "Reversed" also triggers "DirectionVector" - // Re-orient all arrows - Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); - Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); - if (forceDirection.Length() < Precision::Confusion()) - forceDirection = normal; - - SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); - SbRotation rot(SbVec3f(0,1,0), dir); - - const std::vector& points = pcConstraint->Points.getValues(); - -#ifdef USE_MULTIPLE_COPY - SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); - cp->matrix.setNum(points.size()); - SbMatrix* matrices = cp->matrix.startEditing(); -#endif - int idx = 0; - - for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { - SbVec3f base(p->x, p->y, p->z); - if (forceDirection.GetAngle(normal) < M_PI_2) - base = base + dir * scaledlength; //OvG: Scaling -#ifdef USE_MULTIPLE_COPY - SbMatrix m; - m.setTransform(base, rot, SbVec3f(1,1,1)); - matrices[idx] = m; -#else - SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); - updatePlacement(sep, 0, base, rot); - updateArrow(sep, 2, scaledlength, scaledheadradius); //OvG: Scaling -#endif - idx++; - } -#ifdef USE_MULTIPLE_COPY - cp->matrix.finishEditing(); -#endif - } - - ViewProviderFemConstraint::updateData(prop); -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintForce.h" +#include +#include "TaskFemConstraintForce.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintForce::ViewProviderFemConstraintForce() +{ + sPixmap = "fem-constraint-force"; +} + +ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce() +{ +} + +bool ViewProviderFemConstraintForce::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintForce *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // This case will occur in the ShaftWizard application + checkForWizard(); + if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { + // No shaft wizard is running + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } else if (constraintDialog != NULL) { + // Another FemConstraint* dialog is already open inside the Shaft Wizard + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintForce(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintForce(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +#define ARROWLENGTH (4) +#define ARROWHEADRADIUS (ARROWLENGTH/3) +//#define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so disable + +void ViewProviderFemConstraintForce::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); + float scaledheadradius = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue(); + +#ifdef USE_MULTIPLE_COPY + //OvG: need access to cp for scaling + SoMultipleCopy* cp = new SoMultipleCopy(); + if (pShapeSep->getNumChildren() == 0) { + // Set up the nodes + cp->matrix.setNum(0); + cp->addChild((SoNode*)createArrow(scaledlength , scaledheadradius)); //OvG: Scaling + pShapeSep->addChild(cp); + } +#endif + + if (strcmp(prop->getName(),"Points") == 0) { + const std::vector& points = pcConstraint->Points.getValues(); + +#ifdef USE_MULTIPLE_COPY + cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + SbMatrix* matrices = cp->matrix.startEditing(); + int idx = 0; +#else + // Redraw all arrows + pShapeSep->removeAllChildren(); +#endif + // This should always point outside of the solid + Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); + + // Get default direction (on first call to method) + Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); + if (forceDirection.Length() < Precision::Confusion()) + forceDirection = normal; + + SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + if (forceDirection.GetAngle(normal) < M_PI_2) // Move arrow so it doesn't disappear inside the solid + base = base + dir * scaledlength; //OvG: Scaling +#ifdef USE_MULTIPLE_COPY + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + matrices[idx] = m; + idx++; +#else + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, base, rot); + createArrow(sep, scaledlength, scaledheadradius); //OvG: Scaling + pShapeSep->addChild(sep); +#endif + } +#ifdef USE_MULTIPLE_COPY + cp->matrix.finishEditing(); +#endif + } + else if (strcmp(prop->getName(),"DirectionVector") == 0) { // Note: "Reversed" also triggers "DirectionVector" + // Re-orient all arrows + Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue(); + if (forceDirection.Length() < Precision::Confusion()) + forceDirection = normal; + + SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + const std::vector& points = pcConstraint->Points.getValues(); + +#ifdef USE_MULTIPLE_COPY + SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + SbMatrix* matrices = cp->matrix.startEditing(); +#endif + int idx = 0; + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + if (forceDirection.GetAngle(normal) < M_PI_2) + base = base + dir * scaledlength; //OvG: Scaling +#ifdef USE_MULTIPLE_COPY + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + matrices[idx] = m; +#else + SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); + updatePlacement(sep, 0, base, rot); + updateArrow(sep, 2, scaledlength, scaledheadradius); //OvG: Scaling +#endif + idx++; + } +#ifdef USE_MULTIPLE_COPY + cp->matrix.finishEditing(); +#endif + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h index e8b148748e72..55d6187a41e7 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h @@ -1,54 +1,54 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H -#define GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H - -#include "ViewProviderFemConstraint.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemConstraintForce : public FemGui::ViewProviderFemConstraint -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraintForce); - -public: - /// Constructor - ViewProviderFemConstraintForce(); - virtual ~ViewProviderFemConstraintForce(); - - virtual void updateData(const App::Property*); - -protected: - virtual bool setEdit(int ModNum); - -private: - /// Direction of the force - Base::Vector3f forceDirection; -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintForce : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintForce); + +public: + /// Constructor + ViewProviderFemConstraintForce(); + virtual ~ViewProviderFemConstraintForce(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +private: + /// Direction of the force + Base::Vector3f forceDirection; +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp index d07e3d8aefbb..ed93a3a1d415 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp @@ -1,193 +1,193 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraintGear.h" -#include -#include "TaskFemConstraintGear.h" -#include "Gui/Control.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintGear, FemGui::ViewProviderFemConstraint) - - -ViewProviderFemConstraintGear::ViewProviderFemConstraintGear() -{ - sPixmap = "fem-constraint-gear"; -} - -ViewProviderFemConstraintGear::~ViewProviderFemConstraintGear() -{ -} - -bool ViewProviderFemConstraintGear::setEdit(int ModNum) -{ - Base::Console().Error("ViewProviderFemConstraintGear::setEdit()\n"); - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraintGear *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - // This case will occur in the ShaftWizard application - checkForWizard(); - if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { - // No shaft wizard is running - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } else if (constraintDialog != NULL) { - // Another FemConstraint* dialog is already open inside the Shaft Wizard - // Ignore the request to open another dialog - return false; - } else { - constraintDialog = new TaskFemConstraintGear(this); - return true; - } - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraintGear(this)); - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -void ViewProviderFemConstraintGear::updateData(const App::Property* prop) -{ - Fem::ConstraintGear* pcConstraint = static_cast(this->getObject()); - - // Gets called whenever a property of the attached object changes - if (strcmp(prop->getName(),"BasePoint") == 0) { - if (pcConstraint->Height.getValue() > Precision::Confusion()) { - // Remove and recreate the symbol - pShapeSep->removeAllChildren(); - - Base::Vector3d base = pcConstraint->BasePoint.getValue(); - Base::Vector3d axis = pcConstraint->Axis.getValue(); - Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); - if (direction.Length() < Precision::Confusion()) - direction = Base::Vector3d(0,1,0); - double radius = pcConstraint->Radius.getValue(); - double dia = pcConstraint->Diameter.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - - SbVec3f b(base.x, base.y, base.z); - SbVec3f ax(axis.x, axis.y, axis.z); - SbVec3f dir(direction.x, direction.y, direction.z); - //Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y, direction.z); - - createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); - pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); - createPlacement(pShapeSep, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); - pShapeSep->addChild(createArrow(dia/2, dia/8)); - } - } else if (strcmp(prop->getName(),"Diameter") == 0) { - if (pShapeSep->getNumChildren() > 0) { - // Change the symbol - Base::Vector3d axis = pcConstraint->Axis.getValue(); - Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); - if (direction.Length() < Precision::Confusion()) - direction = Base::Vector3d(0,1,0); - double dia = pcConstraint->Diameter.getValue(); - double radius = pcConstraint->Radius.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - - SbVec3f ax(axis.x, axis.y, axis.z); - SbVec3f dir(direction.x, direction.y, direction.z); - - const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); - updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); - sep = static_cast(pShapeSep->getChild(5)); - updateArrow(sep, 0, dia/2, dia/8); - } - } else if ((strcmp(prop->getName(),"DirectionVector") == 0) || (strcmp(prop->getName(),"ForceAngle") == 0)) { - // Note: "Reversed" also triggers "DirectionVector" - if (pShapeSep->getNumChildren() > 0) { - // Re-orient the symbol - Base::Vector3d axis = pcConstraint->Axis.getValue(); - Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); - if (direction.Length() < Precision::Confusion()) - direction = Base::Vector3d(0,1,0); - double dia = pcConstraint->Diameter.getValue(); - double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - - SbVec3f ax(axis.x, axis.y, axis.z); - SbVec3f dir(direction.x, direction.y, direction.z); - /*Base::Console().Error("Axis: %f, %f, %f\n", axis.x, axis.y, axis.z); - Base::Console().Error("Direction: %f, %f, %f\n", direction.x, direction.y, direction.z); - SbRotation rot = SbRotation(ax, dir); - SbMatrix m; - rot.getValue(m); - SbMat m2; - m.getValue(m2); - Base::Console().Error("Matrix: %f, %f, %f, %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); - // Note: In spite of the fact that the rotation matrix takes on 3 different values if 3 - // normal directions are chosen, the resulting arrow will only point in two different - // directions when ax = (1,0,0) (but for ax=(0,1,0) it points in 3 different directions!) - */ - - updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); - } - } - - ViewProviderFemConstraint::updateData(prop); -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintGear.h" +#include +#include "TaskFemConstraintGear.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintGear, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintGear::ViewProviderFemConstraintGear() +{ + sPixmap = "fem-constraint-gear"; +} + +ViewProviderFemConstraintGear::~ViewProviderFemConstraintGear() +{ +} + +bool ViewProviderFemConstraintGear::setEdit(int ModNum) +{ + Base::Console().Error("ViewProviderFemConstraintGear::setEdit()\n"); + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintGear *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // This case will occur in the ShaftWizard application + checkForWizard(); + if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { + // No shaft wizard is running + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } else if (constraintDialog != NULL) { + // Another FemConstraint* dialog is already open inside the Shaft Wizard + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintGear(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintGear(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintGear::updateData(const App::Property* prop) +{ + Fem::ConstraintGear* pcConstraint = static_cast(this->getObject()); + + // Gets called whenever a property of the attached object changes + if (strcmp(prop->getName(),"BasePoint") == 0) { + if (pcConstraint->Height.getValue() > Precision::Confusion()) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + Base::Vector3d base = pcConstraint->BasePoint.getValue(); + Base::Vector3d axis = pcConstraint->Axis.getValue(); + Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); + if (direction.Length() < Precision::Confusion()) + direction = Base::Vector3d(0,1,0); + double radius = pcConstraint->Radius.getValue(); + double dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f ax(axis.x, axis.y, axis.z); + SbVec3f dir(direction.x, direction.y, direction.z); + //Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y, direction.z); + + createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); + pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); + createPlacement(pShapeSep, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); + pShapeSep->addChild(createArrow(dia/2, dia/8)); + } + } else if (strcmp(prop->getName(),"Diameter") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + Base::Vector3d axis = pcConstraint->Axis.getValue(); + Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); + if (direction.Length() < Precision::Confusion()) + direction = Base::Vector3d(0,1,0); + double dia = pcConstraint->Diameter.getValue(); + double radius = pcConstraint->Radius.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + + SbVec3f ax(axis.x, axis.y, axis.z); + SbVec3f dir(direction.x, direction.y, direction.z); + + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); + updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); + sep = static_cast(pShapeSep->getChild(5)); + updateArrow(sep, 0, dia/2, dia/8); + } + } else if ((strcmp(prop->getName(),"DirectionVector") == 0) || (strcmp(prop->getName(),"ForceAngle") == 0)) { + // Note: "Reversed" also triggers "DirectionVector" + if (pShapeSep->getNumChildren() > 0) { + // Re-orient the symbol + Base::Vector3d axis = pcConstraint->Axis.getValue(); + Base::Vector3d direction = pcConstraint->DirectionVector.getValue(); + if (direction.Length() < Precision::Confusion()) + direction = Base::Vector3d(0,1,0); + double dia = pcConstraint->Diameter.getValue(); + double angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + + SbVec3f ax(axis.x, axis.y, axis.z); + SbVec3f dir(direction.x, direction.y, direction.z); + /*Base::Console().Error("Axis: %f, %f, %f\n", axis.x, axis.y, axis.z); + Base::Console().Error("Direction: %f, %f, %f\n", direction.x, direction.y, direction.z); + SbRotation rot = SbRotation(ax, dir); + SbMatrix m; + rot.getValue(m); + SbMat m2; + m.getValue(m2); + Base::Console().Error("Matrix: %f, %f, %f, %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); + // Note: In spite of the fact that the rotation matrix takes on 3 different values if 3 + // normal directions are chosen, the resulting arrow will only point in two different + // directions when ax = (1,0,0) (but for ax=(0,1,0) it points in 3 different directions!) + */ + + updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h index 021c6026ee9a..7d115e3ae6ef 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h @@ -1,50 +1,50 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTGear_H -#define GUI_VIEWPROVIDERFEMCONSTRAINTGear_H - -#include "ViewProviderFemConstraint.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemConstraintGear : public FemGui::ViewProviderFemConstraint -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraintGear); - -public: - /// Constructor - ViewProviderFemConstraintGear(); - virtual ~ViewProviderFemConstraintGear(); - - virtual void updateData(const App::Property*); - -protected: - virtual bool setEdit(int ModNum); -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINTGear_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTGear_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTGear_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintGear : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintGear); + +public: + /// Constructor + ViewProviderFemConstraintGear(); + virtual ~ViewProviderFemConstraintGear(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTGear_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp index ba4926b76ef6..871cb7d107a1 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp @@ -1,227 +1,227 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemConstraintPulley.h" -#include -#include "TaskFemConstraintPulley.h" -#include "Gui/Control.h" - -#include - -using namespace FemGui; - -PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPulley, FemGui::ViewProviderFemConstraint) - - -ViewProviderFemConstraintPulley::ViewProviderFemConstraintPulley() -{ - sPixmap = "fem-constraint-pulley"; -} - -ViewProviderFemConstraintPulley::~ViewProviderFemConstraintPulley() -{ -} - -bool ViewProviderFemConstraintPulley::setEdit(int ModNum) -{ - Base::Console().Error("ViewProviderFemConstraintPulley::setEdit()\n"); - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraintPulley *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - // This case will occur in the ShaftWizard application - checkForWizard(); - if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { - // No shaft wizard is running - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } else if (constraintDialog != NULL) { - // Another FemConstraint* dialog is already open inside the Shaft Wizard - // Ignore the request to open another dialog - return false; - } else { - constraintDialog = new TaskFemConstraintPulley(this); - return true; - } - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraintPulley(this)); - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) -{ - // Gets called whenever a property of the attached object changes - Fem::ConstraintPulley* pcConstraint = static_cast(this->getObject()); - - if (strcmp(prop->getName(),"BasePoint") == 0) { - if (pcConstraint->Height.getValue() > Precision::Confusion()) { - // Remove and recreate the symbol - pShapeSep->removeAllChildren(); - - // This should always point outside of the cylinder - Base::Vector3d base = pcConstraint->BasePoint.getValue(); - Base::Vector3d axis = pcConstraint->Axis.getValue(); - double radius = pcConstraint->Radius.getValue(); - double dia = pcConstraint->Diameter.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - double beltAngle = pcConstraint->BeltAngle.getValue(); - double rat1 = 0.8, rat2 = 0.2; - double f1 = pcConstraint->BeltForce1.getValue(); - double f2 = pcConstraint->BeltForce2.getValue(); - if (f1+f2 > Precision::Confusion()) { - rat1 = f1 / (f1+f2); - rat2 = f2 / (f1+f2); - } - - SbVec3f b(base.x, base.y, base.z); - SbVec3f ax(axis.x, axis.y, axis.z); - - createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); // child 0 and 1 - pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); // child 2 - SoSeparator* sep = new SoSeparator(); - createPlacement(sep, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); - createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); - sep->addChild(createArrow(dia/8 + dia/2 * rat1, dia/8)); - pShapeSep->addChild(sep); // child 3 - sep = new SoSeparator(); - createPlacement(sep, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); - createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); - sep->addChild(createArrow(dia/8 + dia/2 * rat2, dia/8)); - pShapeSep->addChild(sep); // child 4 - } - } else if (strcmp(prop->getName(),"Diameter") == 0) { - if (pShapeSep->getNumChildren() > 0) { - // Change the symbol - double radius = pcConstraint->Radius.getValue(); - double dia = pcConstraint->Diameter.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - double beltAngle = pcConstraint->BeltAngle.getValue(); - double rat1 = 0.8, rat2 = 0.2; - double f1 = pcConstraint->BeltForce1.getValue(); - double f2 = pcConstraint->BeltForce2.getValue(); - if (f1+f2 > Precision::Confusion()) { - rat1 = f1 / (f1+f2); - rat2 = f2 / (f1+f2); - } - - const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); - updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); - sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); - updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); - const SoSeparator* subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8); - sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); - updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); - subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8); - } - } else if ((strcmp(prop->getName(), "ForceAngle") == 0) || (strcmp(prop->getName(), "BeltAngle") == 0)) { - if (pShapeSep->getNumChildren() > 0) { - double radius = pcConstraint->Radius.getValue(); - double dia = pcConstraint->Diameter.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; - double beltAngle = pcConstraint->BeltAngle.getValue(); - - const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); - sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), - SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); - } - } else if ((strcmp(prop->getName(), "BeltForce1") == 0) || (strcmp(prop->getName(), "BeltForce2") == 0)) { - if (pShapeSep->getNumChildren() > 0) { - double radius = pcConstraint->Radius.getValue(); - double dia = pcConstraint->Diameter.getValue(); - if (dia < 2 * radius) - dia = 2 * radius; - double rat1 = 0.8, rat2 = 0.2; - double f1 = pcConstraint->BeltForce1.getValue(); - double f2 = pcConstraint->BeltForce2.getValue(); - if (f1+f2 > Precision::Confusion()) { - rat1 = f1 / (f1+f2); - rat2 = f2 / (f1+f2); - } - - const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); - updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); - const SoSeparator* subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8); - sep = static_cast(pShapeSep->getChild(4)); - updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); - subsep = static_cast(sep->getChild(4)); - updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8); - } - } - - ViewProviderFemConstraint::updateData(prop); -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintPulley.h" +#include +#include "TaskFemConstraintPulley.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPulley, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintPulley::ViewProviderFemConstraintPulley() +{ + sPixmap = "fem-constraint-pulley"; +} + +ViewProviderFemConstraintPulley::~ViewProviderFemConstraintPulley() +{ +} + +bool ViewProviderFemConstraintPulley::setEdit(int ModNum) +{ + Base::Console().Error("ViewProviderFemConstraintPulley::setEdit()\n"); + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintPulley *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // This case will occur in the ShaftWizard application + checkForWizard(); + if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) { + // No shaft wizard is running + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } else if (constraintDialog != NULL) { + // Another FemConstraint* dialog is already open inside the Shaft Wizard + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintPulley(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintPulley(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintPulley* pcConstraint = static_cast(this->getObject()); + + if (strcmp(prop->getName(),"BasePoint") == 0) { + if (pcConstraint->Height.getValue() > Precision::Confusion()) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + // This should always point outside of the cylinder + Base::Vector3d base = pcConstraint->BasePoint.getValue(); + Base::Vector3d axis = pcConstraint->Axis.getValue(); + double radius = pcConstraint->Radius.getValue(); + double dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + double beltAngle = pcConstraint->BeltAngle.getValue(); + double rat1 = 0.8, rat2 = 0.2; + double f1 = pcConstraint->BeltForce1.getValue(); + double f2 = pcConstraint->BeltForce2.getValue(); + if (f1+f2 > Precision::Confusion()) { + rat1 = f1 / (f1+f2); + rat2 = f2 / (f1+f2); + } + + SbVec3f b(base.x, base.y, base.z); + SbVec3f ax(axis.x, axis.y, axis.z); + + createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); // child 0 and 1 + pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); // child 2 + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); + createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); + sep->addChild(createArrow(dia/8 + dia/2 * rat1, dia/8)); + pShapeSep->addChild(sep); // child 3 + sep = new SoSeparator(); + createPlacement(sep, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); + createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); + sep->addChild(createArrow(dia/8 + dia/2 * rat2, dia/8)); + pShapeSep->addChild(sep); // child 4 + } + } else if (strcmp(prop->getName(),"Diameter") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + double radius = pcConstraint->Radius.getValue(); + double dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + double beltAngle = pcConstraint->BeltAngle.getValue(); + double rat1 = 0.8, rat2 = 0.2; + double f1 = pcConstraint->BeltForce1.getValue(); + double f2 = pcConstraint->BeltForce2.getValue(); + if (f1+f2 > Precision::Confusion()) { + rat1 = f1 / (f1+f2); + rat2 = f2 / (f1+f2); + } + + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); + sep = static_cast(pShapeSep->getChild(3)); + updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); + updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); + const SoSeparator* subsep = static_cast(sep->getChild(4)); + updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8); + sep = static_cast(pShapeSep->getChild(4)); + updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); + updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); + subsep = static_cast(sep->getChild(4)); + updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8); + } + } else if ((strcmp(prop->getName(), "ForceAngle") == 0) || (strcmp(prop->getName(), "BeltAngle") == 0)) { + if (pShapeSep->getNumChildren() > 0) { + double radius = pcConstraint->Radius.getValue(); + double dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; + double beltAngle = pcConstraint->BeltAngle.getValue(); + + const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); + updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2)))); + sep = static_cast(pShapeSep->getChild(4)); + updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)), + SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2)))); + } + } else if ((strcmp(prop->getName(), "BeltForce1") == 0) || (strcmp(prop->getName(), "BeltForce2") == 0)) { + if (pShapeSep->getNumChildren() > 0) { + double radius = pcConstraint->Radius.getValue(); + double dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + double rat1 = 0.8, rat2 = 0.2; + double f1 = pcConstraint->BeltForce1.getValue(); + double f2 = pcConstraint->BeltForce2.getValue(); + if (f1+f2 > Precision::Confusion()) { + rat1 = f1 / (f1+f2); + rat2 = f2 / (f1+f2); + } + + const SoSeparator* sep = static_cast(pShapeSep->getChild(3)); + updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation()); + const SoSeparator* subsep = static_cast(sep->getChild(4)); + updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8); + sep = static_cast(pShapeSep->getChild(4)); + updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation()); + subsep = static_cast(sep->getChild(4)); + updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h index 518da789b0b9..5595aa3dd05b 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h @@ -1,50 +1,50 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H -#define GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H - -#include "ViewProviderFemConstraint.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemConstraintPulley : public FemGui::ViewProviderFemConstraint -{ - PROPERTY_HEADER(FemGui::ViewProviderFemConstraintPulley); - -public: - /// Constructor - ViewProviderFemConstraintPulley(); - virtual ~ViewProviderFemConstraintPulley(); - - virtual void updateData(const App::Property*); - -protected: - virtual bool setEdit(int ModNum); -}; - -} //namespace FemGui - - -#endif // GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintPulley : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintPulley); + +public: + /// Constructor + ViewProviderFemConstraintPulley(); + virtual ~ViewProviderFemConstraintPulley(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp index e95839becd06..067946f26ef3 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp @@ -1,2466 +1,2466 @@ -/*************************************************************************** - * Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "ViewProviderFemMesh.h" -#include "ViewProviderFemMeshPy.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace FemGui; - - -struct FemFace -{ - const SMDS_MeshNode *Nodes[8]; - unsigned long ElementNumber; - const SMDS_MeshElement* Element; - unsigned short Size; - unsigned short FaceNo; - bool hide; - Base::Vector3d getFirstNodePoint(void) { - return Base::Vector3d(Nodes[0]->X(),Nodes[0]->Y(),Nodes[0]->Z()); - } - - Base::Vector3d set(short size,const SMDS_MeshElement* element,unsigned short id, short faceNo, - const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4=0, - const SMDS_MeshNode* n5=0,const SMDS_MeshNode* n6=0,const SMDS_MeshNode* n7=0,const SMDS_MeshNode* n8=0); - - bool isSameFace (FemFace &face); -}; - -Base::Vector3d FemFace::set(short size,const SMDS_MeshElement* element,unsigned short id,short faceNo, - const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4, - const SMDS_MeshNode* n5,const SMDS_MeshNode* n6,const SMDS_MeshNode* n7,const SMDS_MeshNode* n8) -{ - Nodes[0] = n1; - Nodes[1] = n2; - Nodes[2] = n3; - Nodes[3] = n4; - Nodes[4] = n5; - Nodes[5] = n6; - Nodes[6] = n7; - Nodes[7] = n8; - - Element = element; - ElementNumber = id; - Size = size; - FaceNo = faceNo; - hide = false; - - // sorting the nodes for later easier comparison (bubble sort) - int i, j, flag = 1; // set flag to 1 to start first pass - const SMDS_MeshNode* temp; // holding variable - - for(i = 1; (i <= size) && flag; i++) - { - flag = 0; - for (j=0; j < (size -1); j++) - { - if (Nodes[j+1] > Nodes[j]) // ascending order simply changes to < - { - temp = Nodes[j]; // swap elements - Nodes[j] = Nodes[j+1]; - Nodes[j+1] = temp; - flag = 1; // indicates that a swap occurred. - } - } - } - - return Base::Vector3d(Nodes[0]->X(),Nodes[0]->Y(),Nodes[0]->Z()); -} - -class FemFaceGridItem : public std::vector{ -public: - //FemFaceGridItem(void){reserve(200);} -}; - -bool FemFace::isSameFace (FemFace &face) -{ - // the same element can not have the same face - if(face.ElementNumber == ElementNumber) - return false; - if(face.Size != Size) - return false; - // if the same face size just compare if the sorted nodes are the same - if( Nodes[0] == face.Nodes[0] && - Nodes[1] == face.Nodes[1] && - Nodes[2] == face.Nodes[2] && - Nodes[3] == face.Nodes[3] && - Nodes[4] == face.Nodes[4] && - Nodes[5] == face.Nodes[5] && - Nodes[6] == face.Nodes[6] && - Nodes[7] == face.Nodes[7] ){ - hide = true; - face.hide = true; - return true; - } - - return false; -}; - -// ---------------------------------------------------------------------------- - -class ViewProviderFemMesh::Private -{ -public: - static const char *dm_face_wire; - static const char *dm_face_wire_node; - static const char *dm_face; - static const char *dm_node; - static const char *dm_wire; -}; - -const char * ViewProviderFemMesh::Private::dm_face_wire = "Faces & Wireframe"; -const char * ViewProviderFemMesh::Private::dm_face_wire_node = "Faces, Wireframe & Nodes"; -const char * ViewProviderFemMesh::Private::dm_face = "Faces"; -const char * ViewProviderFemMesh::Private::dm_node = "Nodes"; -const char * ViewProviderFemMesh::Private::dm_wire = "Wireframe"; - -PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject) - -App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0,64.0,1.0}; - -ViewProviderFemMesh::ViewProviderFemMesh() -{ - sPixmap = "fem-fem-mesh-from-shape"; - - ADD_PROPERTY(PointColor,(App::Color(0.7f,0.7f,0.7f))); - ADD_PROPERTY(PointSize,(5.0f)); - PointSize.setConstraints(&floatRange); - ADD_PROPERTY(LineWidth,(2.0f)); - LineWidth.setConstraints(&floatRange); - - ShapeColor.setValue(App::Color(1.0f,0.7f,0.0f)); - ADD_PROPERTY(BackfaceCulling,(true)); - ADD_PROPERTY(ShowInner, (false)); - - onlyEdges = false; - - pcDrawStyle = new SoDrawStyle(); - pcDrawStyle->ref(); - pcDrawStyle->style = SoDrawStyle::LINES; - pcDrawStyle->lineWidth = LineWidth.getValue(); - - pShapeHints = new SoShapeHints; - pShapeHints->shapeType = SoShapeHints::SOLID; - pShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; - pShapeHints->ref(); - - pcMatBinding = new SoMaterialBinding; - pcMatBinding->value = SoMaterialBinding::OVERALL; - pcMatBinding->ref(); - - pcCoords = new SoCoordinate3(); - pcCoords->ref(); - - pcAnoCoords = new SoCoordinate3(); - pcAnoCoords->ref(); - pcAnoCoords->point.setNum(0); - - pcFaces = new SoIndexedFaceSet; - pcFaces->ref(); - - pcLines = new SoIndexedLineSet; - pcLines->ref(); - - pcPointStyle = new SoDrawStyle(); - pcPointStyle->ref(); - pcPointStyle->style = SoDrawStyle::POINTS; - pcPointStyle->pointSize = PointSize.getValue(); - - pcPointMaterial = new SoMaterial; - pcPointMaterial->ref(); - //PointMaterial.touch(); - - DisplacementFactor = 0; -} - -ViewProviderFemMesh::~ViewProviderFemMesh() -{ - pcCoords->unref(); - pcDrawStyle->unref(); - pcFaces->unref(); - pcLines->unref(); - pShapeHints->unref(); - pcMatBinding->unref(); - pcPointMaterial->unref(); - pcPointStyle->unref(); - pcAnoCoords->unref(); -} - -void ViewProviderFemMesh::attach(App::DocumentObject *pcObj) -{ - ViewProviderGeometryObject::attach(pcObj); - - // Move 'coords' before the switch - //pcRoot->insertChild(pcCoords,pcRoot->findChild(reinterpret_cast(pcModeSwitch))); - - // Annotation sets - SoGroup* pcAnotRoot = new SoAnnotation(); - - SoDrawStyle *pcAnoStyle = new SoDrawStyle(); - pcAnoStyle->style = SoDrawStyle::POINTS; - pcAnoStyle->pointSize = 5; - - SoMaterial *pcAnoMaterial = new SoMaterial; - pcAnoMaterial->diffuseColor.setValue(0,1,0); - pcAnoMaterial->emissiveColor.setValue(0,1,0); - pcAnotRoot->addChild(pcAnoMaterial); - pcAnotRoot->addChild(pcAnoStyle); - pcAnotRoot->addChild(pcAnoCoords); - SoPointSet *pointset = new SoPointSet; - pcAnotRoot->addChild(pointset); - - // flat - SoGroup* pcFlatRoot = new SoGroup(); - // face nodes - pcFlatRoot->addChild(pcCoords); - pcFlatRoot->addChild(pShapeHints); - pcFlatRoot->addChild(pcShapeMaterial); - pcFlatRoot->addChild(pcMatBinding); - pcFlatRoot->addChild(pcFaces); - pcFlatRoot->addChild(pcAnotRoot); - addDisplayMaskMode(pcFlatRoot, Private::dm_face); - - // line - SoLightModel* pcLightModel = new SoLightModel(); - pcLightModel->model = SoLightModel::BASE_COLOR; - SoGroup* pcWireRoot = new SoGroup(); - pcWireRoot->addChild(pcCoords); - pcWireRoot->addChild(pcDrawStyle); - pcWireRoot->addChild(pcLightModel); - SoBaseColor* color = new SoBaseColor(); - color->rgb.setValue(0.0f,0.0f,0.0f); - pcWireRoot->addChild(color); - pcWireRoot->addChild(pcLines); - addDisplayMaskMode(pcWireRoot, Private::dm_wire); - - - // Points - SoGroup* pcPointsRoot = new SoSeparator(); - pcPointsRoot->addChild(pcPointMaterial); - pcPointsRoot->addChild(pcPointStyle); - pcPointsRoot->addChild(pcCoords); - pointset = new SoPointSet; - pcPointsRoot->addChild(pointset); - addDisplayMaskMode(pcPointsRoot, Private::dm_node); - - // flat+line (Elements) - SoPolygonOffset* offset = new SoPolygonOffset(); - offset->styles = SoPolygonOffset::LINES; - //offset->factor = 2.0f; - //offset->units = 1.0f; - SoGroup* pcFlatWireRoot = new SoSeparator(); - // add the complete flat group (contains the coordinates) - pcFlatWireRoot->addChild(pcFlatRoot); - //pcFlatWireRoot->addChild(offset); // makes no differents..... - // add the line nodes - SoMaterialBinding *pcMatBind = new SoMaterialBinding; - pcMatBind->value = SoMaterialBinding::OVERALL; - pcFlatWireRoot->addChild(pcMatBind); - pcFlatWireRoot->addChild(pcDrawStyle); - pcFlatWireRoot->addChild(pcLightModel); - pcFlatWireRoot->addChild(color); - pcFlatWireRoot->addChild(pcLines); - - addDisplayMaskMode(pcFlatWireRoot, Private::dm_face_wire); - - // flat+line+Nodes (Elements&Nodes) - SoGroup* pcElemNodesRoot = new SoSeparator(); - // add the complete flat group (contains the coordinates) - pcElemNodesRoot->addChild(pcFlatRoot); - //pcElemNodesRoot->addChild(offset); - // add the line nodes - pcElemNodesRoot->addChild(pcDrawStyle); - pcElemNodesRoot->addChild(pcLightModel); - pcElemNodesRoot->addChild(color); - pcElemNodesRoot->addChild(pcLines); - // add the points nodes - pcElemNodesRoot->addChild(pcPointMaterial); - pcElemNodesRoot->addChild(pcPointStyle); - pcElemNodesRoot->addChild(pcPointMaterial); - pcElemNodesRoot->addChild(pointset); - - addDisplayMaskMode(pcElemNodesRoot, Private::dm_face_wire_node); -} - -void ViewProviderFemMesh::setDisplayMode(const char* ModeName) -{ - setDisplayMaskMode(ModeName); - ViewProviderGeometryObject::setDisplayMode(ModeName); -} - -std::vector ViewProviderFemMesh::getDisplayModes(void) const -{ - std::vector StrList; - StrList.push_back(Private::dm_face_wire); - StrList.push_back(Private::dm_face_wire_node); - StrList.push_back(Private::dm_face); - StrList.push_back(Private::dm_wire); - StrList.push_back(Private::dm_node); - return StrList; -} - -void ViewProviderFemMesh::updateData(const App::Property* prop) -{ - if (prop->isDerivedFrom(Fem::PropertyFemMesh::getClassTypeId())) { - ViewProviderFEMMeshBuilder builder; - resetColorByNodeId(); - resetDisplacementByNodeId(); - builder.createMesh(prop, pcCoords, pcFaces, pcLines, vFaceElementIdx, vNodeElementIdx, onlyEdges, ShowInner.getValue()); - } - Gui::ViewProviderGeometryObject::updateData(prop); -} - -void ViewProviderFemMesh::onChanged(const App::Property* prop) -{ - if (prop == &PointSize) { - pcPointStyle->pointSize = PointSize.getValue(); - } - else if (prop == &PointColor) { - const App::Color& c = PointColor.getValue(); - pcPointMaterial->diffuseColor.setValue(c.r,c.g,c.b); - } - else if (prop == &BackfaceCulling) { - if(BackfaceCulling.getValue()){ - pShapeHints->shapeType = SoShapeHints::SOLID; - //pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE; - }else{ - pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; - //pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE; - } - } - else if (prop == &ShowInner ) { - // recalc mesh with new settings - ViewProviderFEMMeshBuilder builder; - builder.createMesh(&(dynamic_cast(this->pcObject)->FemMesh), pcCoords, pcFaces, pcLines, vFaceElementIdx, vNodeElementIdx, onlyEdges, ShowInner.getValue()); - } - else if (prop == &LineWidth) { - pcDrawStyle->lineWidth = LineWidth.getValue(); - } - else { - ViewProviderGeometryObject::onChanged(prop); - } -} - -std::string ViewProviderFemMesh::getElement(const SoDetail* detail) const -{ - std::stringstream str; - if (detail) { - if (detail->getTypeId() == SoFaceDetail::getClassTypeId()) { - const SoFaceDetail* face_detail = static_cast(detail); - unsigned long edx = vFaceElementIdx[face_detail->getFaceIndex()]; - - str << "Elem" << (edx>>3) << "F"<< (edx&7)+1; - } - // trigger on edges only if edge only mesh, otherwise you only hit edges an never faces.... - else if (onlyEdges && detail->getTypeId() == SoLineDetail::getClassTypeId()) { - const SoLineDetail* line_detail = static_cast(detail); - int edge = line_detail->getLineIndex() + 1; - str << "Edge" << edge; - } - else if (detail->getTypeId() == SoPointDetail::getClassTypeId()) { - const SoPointDetail* point_detail = static_cast(detail); - int idx = point_detail->getCoordinateIndex(); - if (idx < static_cast(vNodeElementIdx.size())) { - int vertex = vNodeElementIdx[point_detail->getCoordinateIndex()]; - str << "Node" << vertex; - } - else { - return std::string(); - } - } - } - - return str.str(); -} - -SoDetail* ViewProviderFemMesh::getDetail(const char* subelement) const -{ - std::string element = subelement; - std::string::size_type pos = element.find_first_of("0123456789"); - int index = -1; - if (pos != std::string::npos) { - index = std::atoi(element.substr(pos).c_str()); - element = element.substr(0,pos); - } - - SoDetail* detail = 0; - if (index < 0) - return detail; - if (element == "Elem") { - detail = new SoFaceDetail(); - static_cast(detail)->setPartIndex(index - 1); - } - //else if (element == "Edge") { - // detail = new SoLineDetail(); - // static_cast(detail)->setLineIndex(index - 1); - //} - //else if (element == "Vertex") { - // detail = new SoPointDetail(); - // static_cast(detail)->setCoordinateIndex(index + nodeset->startIndex.getValue() - 1); - //} - - return detail; -} - -std::vector ViewProviderFemMesh::getSelectionShape(const char* Element) const -{ - return std::vector(); -} - -void ViewProviderFemMesh::setHighlightNodes(const std::set& HighlightedNodes) -{ - if(!HighlightedNodes.empty()){ - SMESHDS_Mesh* data = const_cast((dynamic_cast(this->pcObject)->FemMesh).getValue().getSMesh())->GetMeshDS(); - - pcAnoCoords->point.setNum(HighlightedNodes.size()); - SbVec3f* verts = pcAnoCoords->point.startEditing(); - int i=0; - for(std::set::const_iterator it=HighlightedNodes.begin();it!=HighlightedNodes.end();++it,i++){ - const SMDS_MeshNode *Node = data->FindNode(*it); - if (Node) - verts[i].setValue((float)Node->X(),(float)Node->Y(),(float)Node->Z()); - else - verts[i].setValue(0,0,0); - } - pcAnoCoords->point.finishEditing(); - }else{ - pcAnoCoords->point.setNum(0); - } -} -void ViewProviderFemMesh::resetHighlightNodes(void) -{ - pcAnoCoords->point.setNum(0); -} - -PyObject * ViewProviderFemMesh::getPyObject() -{ - if (PythonObject.is(Py::_None())){ - // ref counter is set to 1 - PythonObject = Py::Object(new ViewProviderFemMeshPy(this),true); - } - return Py::new_reference_to(PythonObject); -} - -void ViewProviderFemMesh::setColorByNodeId(const std::map &NodeColorMap) -{ - long startId = NodeColorMap.begin()->first; - long endId = (--NodeColorMap.end())->first; - - std::vector colorVec(endId-startId+2,App::Color(0,1,0)); - for(std::map::const_iterator it=NodeColorMap.begin();it!=NodeColorMap.end();++it) - colorVec[it->first-startId] = it->second; - - setColorByNodeIdHelper(colorVec); - -} -void ViewProviderFemMesh::setColorByNodeId(const std::vector &NodeIds,const std::vector &NodeColors) -{ - - long startId = *(std::min_element(NodeIds.begin(), NodeIds.end())); - long endId = *(std::max_element(NodeIds.begin(), NodeIds.end())); - - std::vector colorVec(endId-startId+2,App::Color(0,1,0)); - long i=0; - for(std::vector::const_iterator it=NodeIds.begin();it!=NodeIds.end();++it,i++) - colorVec[*it-startId] = NodeColors[i]; - - - setColorByNodeIdHelper(colorVec); - -} - -void ViewProviderFemMesh::setColorByNodeIdHelper(const std::vector &colorVec) -{ - pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; - - // resizing and writing the color vector: - pcShapeMaterial->diffuseColor.setNum(vNodeElementIdx.size()); - SbColor* colors = pcShapeMaterial->diffuseColor.startEditing(); - - long i=0; - for(std::vector::const_iterator it=vNodeElementIdx.begin() - ;it!=vNodeElementIdx.end() - ;++it,i++) - colors[i] = SbColor(colorVec[*it-1].r,colorVec[*it-1].g,colorVec[*it-1].b); - - - pcShapeMaterial->diffuseColor.finishEditing(); -} - -void ViewProviderFemMesh::resetColorByNodeId(void) -{ - pcMatBinding->value = SoMaterialBinding::OVERALL; - pcShapeMaterial->diffuseColor.setNum(0); - const App::Color& c = ShapeColor.getValue(); - pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b); - -} - -void ViewProviderFemMesh::setDisplacementByNodeId(const std::map &NodeDispMap) -{ - long startId = NodeDispMap.begin()->first; - long endId = (--NodeDispMap.end())->first; - - std::vector vecVec(endId-startId+2,Base::Vector3d()); - - for(std::map::const_iterator it=NodeDispMap.begin();it!=NodeDispMap.end();++it) - vecVec[it->first-startId] = it->second; - - setDisplacementByNodeIdHelper(vecVec,startId); -} - -void ViewProviderFemMesh::setDisplacementByNodeId(const std::vector &NodeIds,const std::vector &NodeDisps) -{ - long startId = *(std::min_element(NodeIds.begin(), NodeIds.end())); - long endId = *(std::max_element(NodeIds.begin(), NodeIds.end())); - - std::vector vecVec(endId-startId+2,Base::Vector3d()); - - long i=0; - for(std::vector::const_iterator it=NodeIds.begin();it!=NodeIds.end();++it,i++) - vecVec[*it-startId] = NodeDisps[i]; - - setDisplacementByNodeIdHelper(vecVec,startId); -} - -void ViewProviderFemMesh::setDisplacementByNodeIdHelper(const std::vector& DispVector,long startId) -{ - DisplacementVector.resize(vNodeElementIdx.size()); - int i=0; - for(std::vector::const_iterator it=vNodeElementIdx.begin();it!=vNodeElementIdx.end();++it,i++) - DisplacementVector[i] = DispVector[*it-startId]; - applyDisplacementToNodes(1.0); - -} - -void ViewProviderFemMesh::resetDisplacementByNodeId(void) -{ - applyDisplacementToNodes(0.0); - DisplacementVector.clear(); -} -/// reaply the node displacement with a certain factor and do a redraw -void ViewProviderFemMesh::applyDisplacementToNodes(double factor) -{ - if(DisplacementVector.size() == 0) - return; - - float x,y,z; - // set the point coordinates - long sz = pcCoords->point.getNum(); - SbVec3f* verts = pcCoords->point.startEditing(); - for (long i=0;i < sz ;i++) { - verts[i].getValue(x,y,z); - // undo old factor# - Base::Vector3d oldDisp = DisplacementVector[i] * DisplacementFactor; - x -= oldDisp.x; - y -= oldDisp.y; - z -= oldDisp.z; - // apply new factor - Base::Vector3d newDisp = DisplacementVector[i] * factor; - x += newDisp.x; - y += newDisp.y; - z += newDisp.z; - // set the new value - verts[i].setValue(x,y,z); - } - pcCoords->point.finishEditing(); - - DisplacementFactor = factor; -} - -void ViewProviderFemMesh::setColorByElementId(const std::map &ElementColorMap) -{ - pcMatBinding->value = SoMaterialBinding::PER_FACE ; - - // resizing and writing the color vector: - pcShapeMaterial->diffuseColor.setNum(vFaceElementIdx.size()); - SbColor* colors = pcShapeMaterial->diffuseColor.startEditing(); - - int i=0; - for(std::vector::const_iterator it=vFaceElementIdx.begin() - ;it!=vFaceElementIdx.end() - ;++it,i++){ - unsigned long ElemIdx = ((*it)>>3); - const std::map::const_iterator pos = ElementColorMap.find(ElemIdx); - if(pos == ElementColorMap.end()) - colors[i] = SbColor(0,1,0); - else - colors[i] = SbColor(pos->second.r,pos->second.g,pos->second.b); - } - - pcShapeMaterial->diffuseColor.finishEditing(); -} - -void ViewProviderFemMesh::resetColorByElementId(void) -{ - pcMatBinding->value = SoMaterialBinding::OVERALL; - pcShapeMaterial->diffuseColor.setNum(0); - const App::Color& c = ShapeColor.getValue(); - pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b); - -} - -// ---------------------------------------------------------------------------- - -void ViewProviderFEMMeshBuilder::buildNodes(const App::Property* prop, std::vector& nodes) const -{ - SoCoordinate3 *pcPointsCoord=0; - SoIndexedFaceSet *pcFaces=0; - SoIndexedLineSet *pcLines=0; - - if (nodes.empty()) { - pcPointsCoord = new SoCoordinate3(); - nodes.push_back(pcPointsCoord); - pcFaces = new SoIndexedFaceSet(); - pcLines = new SoIndexedLineSet(); - nodes.push_back(pcFaces); - } - else if (nodes.size() == 2) { - if (nodes[0]->getTypeId() == SoCoordinate3::getClassTypeId()) - pcPointsCoord = static_cast(nodes[0]); - if (nodes[1]->getTypeId() == SoIndexedFaceSet::getClassTypeId()) - pcFaces = static_cast(nodes[1]); - } - - if (pcPointsCoord && pcFaces){ - std::vector vFaceElementIdx; - std::vector vNodeElementIdx; - bool onlyEdges; - createMesh(prop, pcPointsCoord, pcFaces,pcLines,vFaceElementIdx,vNodeElementIdx,onlyEdges,false); - } -} - -inline void insEdgeVec(std::map > &map, int n1, int n2) -{ - //FIXME: The if-else distinction doesn't make sense - //if (n1 &vFaceElementIdx, - std::vector &vNodeElementIdx, - bool &onlyEdges, - bool ShowInner) const -{ - - const Fem::PropertyFemMesh* mesh = static_cast(prop); - - SMESHDS_Mesh* data = const_cast(mesh->getValue().getSMesh())->GetMeshDS(); - - int numFaces = data->NbFaces(); - int numNodes = data->NbNodes(); - int numEdges = data->NbEdges(); - - if(numFaces+numNodes+numEdges == 0) return; - Base::TimeInfo Start; - Base::Console().Log("Start: ViewProviderFEMMeshBuilder::createMesh() =================================\n"); - - const SMDS_MeshInfo& info = data->GetMeshInfo(); - int numTria = info.NbTriangles(); - int numQuad = info.NbQuadrangles(); - - int numVolu = info.NbVolumes(); - int numTetr = info.NbTetras(); - int numHexa = info.NbHexas(); - int numPyrd = info.NbPyramids(); - int numPris = info.NbPrisms(); - - - bool ShowFaces = (numFaces >0 && numVolu == 0); - - int numTries; - if(ShowFaces) - numTries = numTria+numQuad/*+numPoly*/+numTetr*4+numHexa*6+numPyrd*5+numPris*5; - else - numTries = numTetr*4+numHexa*6+numPyrd*5+numPris*5; - // It is not 100% sure that a prism in smesh is a pentahedron in any case, but it will be in most cases! - // See http://forum.freecadweb.org/viewtopic.php?f=18&t=13583#p109707 - - // corner case only edges (Beams) in the mesh. This need some special cases in building up visual - onlyEdges = false; - if (numFaces <= 0 && numVolu <= 0 && numEdges > 0){ - onlyEdges = true; - } - - std::vector facesHelper(numTries); - - Base::Console().Log(" %f: Start build up %i face helper\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo()),facesHelper.size()); - Base::BoundBox3d BndBox; - - int i=0; - - if (ShowFaces){ - SMDS_FaceIteratorPtr aFaceIter = data->facesIterator(); - for (;aFaceIter->more();) { - const SMDS_MeshFace* aFace = aFaceIter->next(); - - int num = aFace->NbNodes(); - switch(num){ - case 3: - //tria3 face = N1, N2, N3 - BndBox.Add(facesHelper[i++].set(3, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(1), aFace->GetNode(2))); - break; - case 4: - //quad4 face = N1, N2, N3, N4 - BndBox.Add(facesHelper[i++].set(4, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(1), aFace->GetNode(2), aFace->GetNode(3))); - break; - case 6: - //tria6 face = N1, N4, N2, N5, N3, N6 - BndBox.Add(facesHelper[i++].set(6, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(3), aFace->GetNode(1), aFace->GetNode(4), aFace->GetNode(2), aFace->GetNode(5))); - break; - case 8: - //quad8 face = N1, N5, N2, N6, N3, N7, N4, N8 - BndBox.Add(facesHelper[i++].set(8, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(4), aFace->GetNode(1), aFace->GetNode(5), aFace->GetNode(2), aFace->GetNode(6), aFace->GetNode(3), aFace->GetNode(7))); - break; - default: - //unknown face type - throw std::runtime_error("Node count not supported by ViewProviderFemMesh, [3|4|6|8] are allowed"); - } - } - } - else{ - - // iterate all volumes - SMDS_VolumeIteratorPtr aVolIter = data->volumesIterator(); - for (; aVolIter->more();) { - const SMDS_MeshVolume* aVol = aVolIter->next(); - - int num = aVol->NbNodes(); - - switch (num){ - //tetra4 volume - case 4: - // face 1 = N1, N2, N3 - // face 2 = N1, N4, N2 - // face 3 = N2, N4, N3 - // face 4 = N3, N4, N1 - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(3), aVol->GetNode(1))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(3), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(3), aVol->GetNode(0))); - break; - //pyra5 volume - case 5: - // face 1 = N1, N2, N3, N4 - // face 2 = N1, N5, N2 - // face 3 = N2, N5, N3 - // face 4 = N3, N5, N4 - // face 5 = N4, N5, N1 - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2), aVol->GetNode(3))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(1))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(4), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(4), aVol->GetNode(3))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 5, aVol->GetNode(3), aVol->GetNode(4), aVol->GetNode(0))); - break; - //penta6 volume - case 6: - // face 1 = N1, N2, N3 - // face 2 = N4, N6, N5 - // face 3 = N1, N4, N5, N2 - // face 4 = N2, N5, N6, N3 - // face 5 = N3, N6, N4, N1 - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(3), aVol->GetNode(5), aVol->GetNode(4))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(3), aVol->GetNode(4), aVol->GetNode(1))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(4), aVol->GetNode(5), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(5), aVol->GetNode(3), aVol->GetNode(0))); - break; - //hexa8 volume - case 8: - // face 1 = N1, N2, N3, N4 - // face 2 = N5, N8, N7, N6 - // face 3 = N1, N5, N6, N2 - // face 4 = N2, N6, N7, N3 - // face 5 = N3, N7, N8, N4 - // face 6 = N4, N8, N5, N1 - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2), aVol->GetNode(3))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 2, aVol->GetNode(4), aVol->GetNode(7), aVol->GetNode(6), aVol->GetNode(5))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(5), aVol->GetNode(1))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(5), aVol->GetNode(6), aVol->GetNode(2))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(6), aVol->GetNode(7), aVol->GetNode(3))); - BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 6, aVol->GetNode(3), aVol->GetNode(7), aVol->GetNode(4), aVol->GetNode(0))); - break; - //tetra10 volume - case 10: - // face 1 = N1, N5, N2, N6, N3, N7 - // face 2 = N1, N8, N4, N9, N2, N5 - // face 3 = N2, N9, N4, N10, N3, N6 - // face 4 = N3, N10, N4, N8, N1, N7 - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(1), aVol->GetNode(5), aVol->GetNode(2), aVol->GetNode(6))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(7), aVol->GetNode(3), aVol->GetNode(8), aVol->GetNode(1), aVol->GetNode(4))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(8), aVol->GetNode(3), aVol->GetNode(9), aVol->GetNode(2), aVol->GetNode(5))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(9), aVol->GetNode(3), aVol->GetNode(7), aVol->GetNode(0), aVol->GetNode(6))); - break; - //pyra13 volume - case 13: - // face 1 = N1, N6, N2, N7, N3, N8, N4, N9 - // face 2 = N1, N10, N5, N11, N2, N6 - // face 3 = N2, N11, N5, N12, N3, N7 - // face 4 = N3, N12, N5, N13, N4, N8 - // face 5 = N4, N13, N5, N10, N1, N9 - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(5), aVol->GetNode(1), aVol->GetNode(6), aVol->GetNode(2), aVol->GetNode(7), aVol->GetNode(3), aVol->GetNode(8))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(9), aVol->GetNode(4), aVol->GetNode(10), aVol->GetNode(1), aVol->GetNode(5))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(10), aVol->GetNode(4), aVol->GetNode(11), aVol->GetNode(2), aVol->GetNode(6))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(11), aVol->GetNode(4), aVol->GetNode(12), aVol->GetNode(3), aVol->GetNode(7))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 5, aVol->GetNode(3), aVol->GetNode(12), aVol->GetNode(4), aVol->GetNode(9), aVol->GetNode(0), aVol->GetNode(8))); - break; - //penta15 volume - case 15: - // face 1 = N1, N7, N2, N8, N3, N9 - // face 2 = N4, N12, N6, N11, N5, N10 - // face 3 = N1, N13, N4, N10, N5, N14, N2, N7 - // face 4 = N2, N14, N5, N11, N6, N15, N3, N8 - // face 5 = N3, N15, N6, N12, N4, N13, N1, N9 - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(6), aVol->GetNode(1), aVol->GetNode(7), aVol->GetNode(2), aVol->GetNode(8))); - BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(3), aVol->GetNode(11), aVol->GetNode(5), aVol->GetNode(10), aVol->GetNode(4), aVol->GetNode(9))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(12), aVol->GetNode(3), aVol->GetNode(9), aVol->GetNode(4), aVol->GetNode(13), aVol->GetNode(1), aVol->GetNode(6))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(13), aVol->GetNode(4), aVol->GetNode(10), aVol->GetNode(5), aVol->GetNode(14), aVol->GetNode(2), aVol->GetNode(7))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(14), aVol->GetNode(5), aVol->GetNode(11), aVol->GetNode(3), aVol->GetNode(12), aVol->GetNode(0), aVol->GetNode(8))); - break; - //hexa20 volume - case 20: - // face 1 = N1, N9, N2, N10, N3, N11, N4, N12 - // face 2 = N5, N16, N8, N15, N7, N14, N6, N13 - // face 3 = N1, N17, N5, N13, N6, N18, N2, N9 - // face 4 = N2, N18, N6, N14, N7, N19, N3, N10 - // face 5 = N3, N19, N7, N15, N8, N20, N4, N11 - // face 6 = N4, N20, N8, N16, N5, N17, N1, N12 - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(8), aVol->GetNode(1), aVol->GetNode(9), aVol->GetNode(2), aVol->GetNode(10), aVol->GetNode(3), aVol->GetNode(11))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 2, aVol->GetNode(4), aVol->GetNode(15), aVol->GetNode(7), aVol->GetNode(14), aVol->GetNode(6), aVol->GetNode(13), aVol->GetNode(5), aVol->GetNode(12))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(16), aVol->GetNode(4), aVol->GetNode(12), aVol->GetNode(5), aVol->GetNode(17), aVol->GetNode(1), aVol->GetNode(8))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(17), aVol->GetNode(5), aVol->GetNode(13), aVol->GetNode(6), aVol->GetNode(18), aVol->GetNode(2), aVol->GetNode(9))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(18), aVol->GetNode(6), aVol->GetNode(14), aVol->GetNode(7), aVol->GetNode(19), aVol->GetNode(3), aVol->GetNode(10))); - BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 6, aVol->GetNode(3), aVol->GetNode(19), aVol->GetNode(7), aVol->GetNode(15), aVol->GetNode(4), aVol->GetNode(16), aVol->GetNode(0), aVol->GetNode(11))); - break; - //unknown volume type - default: - throw std::runtime_error("Node count not supported by ViewProviderFemMesh, [4|5|6|8|10|13|15|20] are allowed"); - } - } - } - int FaceSize = facesHelper.size(); - - - if( FaceSize < 5000){ - Base::Console().Log(" %f: Start eliminate internal faces SIMPLE\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - - // search for double (inside) faces and hide them - if(!ShowInner){ - for(int l=0; l< FaceSize;l++){ - if(! facesHelper[l].hide){ - for(int i=l+1; i Grid(NbrX*NbrY*NbrZ); - - - unsigned int iX = 0; - unsigned int iY = 0; - unsigned int iZ = 0; - - for(int l=0; l< FaceSize;l++){ - Base::Vector3d point(facesHelper[l].getFirstNodePoint()); - double x = (point.x - Xmin) / Xln; - double y = (point.y - Ymin) / Yln; - double z = (point.z - Zmin) / Zln; - - iX = x; - iY = y; - iZ = z; - - if(iX >= NbrX || iY >= NbrY || iZ >= NbrZ) - Base::Console().Log(" Outof range!\n"); - - Grid[iX + iY*NbrX + iZ*NbrX*NbrY].push_back(&facesHelper[l]); - } - - unsigned int max =0, avg = 0; - for(std::vector::iterator it=Grid.begin();it!=Grid.end();++it){ - for(unsigned int l=0; l< it->size();l++){ - if(! it->operator[](l)->hide){ - for(unsigned int i=l+1; isize(); i++){ - if(it->operator[](l)->isSameFace(*(it->operator[](i))) ){ - break; - } - } - } - } - if(it->size() > max)max=it->size(); - avg += it->size(); - } - avg = avg/Grid.size(); - - Base::Console().Log(" VoxelSize: Max:%i ,Average:%i\n",max,avg); - - } //if( FaceSize < 1000) - - - Base::Console().Log(" %f: Start build up node map\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - - // sort out double nodes and build up index map - std::map mapNodeIndex; - - // handling the corner case beams only, means no faces/triangles only nodes and edges - if (onlyEdges){ - - SMDS_EdgeIteratorPtr aEdgeIte = data->edgesIterator(); - for (; aEdgeIte->more();) { - const SMDS_MeshEdge* aEdge = aEdgeIte->next(); - int num = aEdge->NbNodes(); - for (int i = 0; i < num; i++) { - mapNodeIndex[aEdge->GetNode(i)] = 0; - - } - } - }else{ - - for (int l = 0; l < FaceSize; l++) { - if (!facesHelper[l].hide) { - for (int i = 0; i < 8; i++) { - if (facesHelper[l].Nodes[i]) - mapNodeIndex[facesHelper[l].Nodes[i]] = 0; - else - break; - } - } - } - } - Base::Console().Log(" %f: Start set point vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - - // set the point coordinates - coords->point.setNum(mapNodeIndex.size()); - vNodeElementIdx.resize(mapNodeIndex.size() ); - std::map::iterator it= mapNodeIndex.begin(); - SbVec3f* verts = coords->point.startEditing(); - for (int i=0;it != mapNodeIndex.end() ;++it,i++) { - verts[i].setValue((float)it->first->X(),(float)it->first->Y(),(float)it->first->Z()); - it->second = i; - // set selection idx - vNodeElementIdx[i] = it->first->GetID(); - } - coords->point.finishEditing(); - - - - // count triangle size - Base::Console().Log(" %f: Start count triangle size\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - int triangleCount=0; - for (int l = 0; l < FaceSize; l++){ - if (!facesHelper[l].hide) - switch (facesHelper[l].Size){ - case 3:triangleCount++; break; // 3-node triangle face --> 1 triangle - case 4:triangleCount += 2; break; // 4-node quadrangle face --> 2 triangles - case 6:triangleCount += 4; break; // 6-node triangle face --> 4 triangles - case 8:triangleCount += 6; break; // 8-node quadrangle face --> 6 triangles - default: throw std::runtime_error("Face with unknown node count found, only display mode nodes is supported for this element (tiangleCount)"); - } - } - Base::Console().Log(" NumTriangles:%i\n",triangleCount); - // edge map collect and sort edges of the faces to be shown. - std::map > EdgeMap; - - // handling the corner case beams only, means no faces/triangles only nodes and edges - if (onlyEdges){ - - SMDS_EdgeIteratorPtr aEdgeIte = data->edgesIterator(); - for (; aEdgeIte->more();) { - const SMDS_MeshEdge* aEdge = aEdgeIte->next(); - int num = aEdge->NbNodes(); - switch (num){ - case 2: { // Seg2: N1, N2 - int nIdx0 = mapNodeIndex[aEdge->GetNode(0)]; - int nIdx1 = mapNodeIndex[aEdge->GetNode(1)]; - insEdgeVec(EdgeMap, nIdx0, nIdx1); - break; - } - - case 3: { // Seg3: N1, N2, N3 (N3 is middle Node) - int nIdx0 = mapNodeIndex[aEdge->GetNode(0)]; - int nIdx1 = mapNodeIndex[aEdge->GetNode(1)]; - int nIdx2 = mapNodeIndex[aEdge->GetNode(2)]; - insEdgeVec(EdgeMap, nIdx0, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx1); - break; - } - } - } - } - - Base::Console().Log(" %f: Start build up triangle vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - // set the triangle face indices - faces->coordIndex.setNum(4*triangleCount); - vFaceElementIdx.resize(triangleCount); - int index=0,indexIdx=0; - int32_t* indices = faces->coordIndex.startEditing(); - // iterate all not hided element faces, allways assure CLOCKWISE triangle ordering to allow backface culling - for(int l=0; l< FaceSize;l++){ - if(! facesHelper[l].hide){ - switch( facesHelper[l].Element->NbNodes()){ - // 3 nodes - case 3: - // tria3 face - switch (facesHelper[l].FaceNo){ - case 0: { // tria3 face, 3-node triangle - // prefeche all node indexes of this face - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - // create triangle number 1 ---------------------------------------------- - // fill in the node indexes in CLOCKWISE order - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - // add the three edge segments for that triangle - insEdgeVec(EdgeMap, nIdx0, nIdx1); - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx0); - // rember the element and face number for that triangle - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - default: assert(0); - } - break; - // 4 nodes - case 4: - // quad4 face - // tetra4 volume, four 3-node triangles - switch (facesHelper[l].FaceNo){ - case 0: { // quad4 face, 4-node quadrangle - // prefeche all node indexes of this face - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - // create triangle number 1 ---------------------------------------------- - // fill in the node indexes in CLOCKWISE order - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - // add the two edge segments for that triangle - insEdgeVec(EdgeMap, nIdx0, nIdx1); - insEdgeVec(EdgeMap, nIdx1, nIdx2); - // rember the element and face number for that triangle - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 2 ---------------------------------------------- - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx2, nIdx3); - insEdgeVec(EdgeMap, nIdx3, nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - case 1: { // tetra4 volume: face 1, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - case 2: { // tetra4 volume: face 2, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - break; } - case 3: { // tetra4 volume: face 3, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - break; } - case 4: { // tetra4 volume: face 4, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - break; } - default: assert(0); - } - break; - // 5 nodes - case 5: - // pyra5 volume, one 4-node quadrangle and four 3-node triangles - switch (facesHelper[l].FaceNo){ - case 1: { // pyra5 volume: face 1, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - case 2: { // pyra5 volume: face 2, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - break; } - case 3: { // pyra5 volume: face 3, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - break; } - case 4: { // pyra5 volume: face 4, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - break; } - case 5: { // pyra5 volume: face 5, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - break; } - default: assert(0); - } - break; - // 6 nodes - case 6: - // tria6 face - // penta6 volume, two 3-node triangle and three 4-node qudrangles - switch (facesHelper[l].FaceNo){ - case 0: { // tria6 face, 6-node triangle - // prefeche all node indexes of this face - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - // create triangle number 1 ---------------------------------------------- - // fill in the node indexes in CLOCKWISE order - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - // add the two edge segments for that triangle - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - // rember the element and face number for that triangle - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 2 ---------------------------------------------- - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 3 ---------------------------------------------- - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 4 ---------------------------------------------- - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - // this triangle has no edge (inner triangle). - break; } - case 1: { // penta6 volume: face 1, 3-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - insEdgeVec(EdgeMap,nIdx2,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - case 2: { // penta6 volume: face 2, 3-node triangle - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx4; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx3,nIdx5); - insEdgeVec(EdgeMap,nIdx5,nIdx4); - insEdgeVec(EdgeMap,nIdx4,nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - break; } - case 3: { // penta6 volume: face 3, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - break; } - case 4: { // penta6 volume: face 4, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - break; } - case 5: { // penta6 volume: face 5, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - break; } - default: assert(0); - } - break; - // 8 nodes - case 8: - // quad8 face - // hexa8 volume, six 4-node quadrangles - switch(facesHelper[l].FaceNo){ - case 0: { // quad8 face, 8-node quadrangle - // prefeche all node indexes of this face - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - // create triangle number 1 ---------------------------------------------- - // fill in the node indexes in CLOCKWISE order - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - // add the two edge segments for that triangle - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - // rember the element and face number for that triangle - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 2 ---------------------------------------------- - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 3 ---------------------------------------------- - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 4 ---------------------------------------------- - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - // create triangle number 5 ---------------------------------------------- - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - // this triangle has no edge (inner triangle) - // create triangle number 6 ---------------------------------------------- - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - // this triangle has no edge (inner triangle) - break; } - case 1: { // hexa8 volume: face 1, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - break; } - case 2: { // hexa8 volume: face 2, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - break; } - case 3: { // hexa8 volume: face 3, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - break; } - case 4: { // hexa8 volume: face 4, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - break; } - case 5: { // hexa8 volume: face 5, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - break; } - case 6: { // hexa8 volume: face 6, 4-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx0,nIdx1); - insEdgeVec(EdgeMap,nIdx1,nIdx2); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = nIdx0; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap,nIdx2,nIdx3); - insEdgeVec(EdgeMap,nIdx3,nIdx0); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - break; } - default: assert(0); - } - break; - // 10 nodes - case 10: - // tetra10 volume, four 6-node triangles - switch(facesHelper[l].FaceNo){ - case 1: { // tetra10 volume: face 1, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 2: { // tetra10 volume: face 2, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 3: { // tetra10 volume: face 3, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 4: { // tetra10 volume: face 4, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - default: assert(0); - } - break; - // 13 nodes - case 13: - // pyra13 volume, four 6-node triangle and one 8-node qudrangles - switch(facesHelper[l].FaceNo){ - case 1: { // pyra13 volume: face 1, 8-node qudrangles - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 2: { // pyra13 volume: face 2, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 3: { // pyra13 volume: face 3, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 4: { // pyra13 volume: face 4, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 5: { // pyra13 volume: face 5, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - default: assert(0); - } - break; - // 15 nodes - case 15: - // penta15 volume, two 6-node triangles and three 8-node qudrangles - switch(facesHelper[l].FaceNo){ - case 1: { // penta15 volume: face 1, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 2: { // penta15 volume: face 2, 6-node triangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - indices[index++] = nIdx5; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 3: { // penta15 volume: face 3, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 4: { // penta15 volume: face 4, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 5: { // penta15 volume: face 5, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - default: assert(0); - } - break; - // 20 nodes - case 20: - // hexa20 volume, six 8-node qudrangles - switch(facesHelper[l].FaceNo){ - case 1: { // hexa20 volume: face 1 - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 2: { // hexa20 volume: face 2, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(15)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 3: { // hexa20 volume: face 3, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(16)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(17)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 4: { // hexa20 volume: face 4, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(17)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(18)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 5: { // hexa20 volume: face 5, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(18)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(19)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - case 6: { // hexa20 volume: face 6, 8-node quadrangle - int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; - int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(19)]; - int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; - int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(15)]; - int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; - int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(16)]; - int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; - int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; - indices[index++] = nIdx7; - indices[index++] = nIdx0; - indices[index++] = nIdx1; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx7, nIdx0); - insEdgeVec(EdgeMap, nIdx0, nIdx1); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - indices[index++] = nIdx1; - indices[index++] = nIdx2; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx1, nIdx2); - insEdgeVec(EdgeMap, nIdx2, nIdx3); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - indices[index++] = nIdx3; - indices[index++] = nIdx4; - indices[index++] = nIdx5; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx3, nIdx4); - insEdgeVec(EdgeMap, nIdx4, nIdx5); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - indices[index++] = nIdx5; - indices[index++] = nIdx6; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - insEdgeVec(EdgeMap, nIdx5, nIdx6); - insEdgeVec(EdgeMap, nIdx6, nIdx7); - vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); - indices[index++] = nIdx7; - indices[index++] = nIdx1; - indices[index++] = nIdx3; - indices[index++] = SO_END_FACE_INDEX; - indices[index++] = nIdx3; - indices[index++] = nIdx5; - indices[index++] = nIdx7; - indices[index++] = SO_END_FACE_INDEX; - break; } - default: assert(0); - } - break; - - // not implemented elements - default: throw std::runtime_error("Element with unknown node count found (may be not implemented), only display mode nodes is supported for this element (NodeCount)"); - } - } - } - - faces->coordIndex.finishEditing(); - - Base::Console().Log(" %f: Start build up edge vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - // std::map > EdgeMap; - // count edges - int EdgeSize = 0; - for(std::map >::const_iterator it= EdgeMap.begin();it!= EdgeMap.end();++it) - EdgeSize += it->second.size(); - - // set the triangle face indices - lines->coordIndex.setNum(3*EdgeSize); - index=0; - indices = lines->coordIndex.startEditing(); - - for(std::map >::const_iterator it= EdgeMap.begin();it!= EdgeMap.end();++it){ - for(std::set::const_iterator it2=it->second.begin();it2!=it->second.end();++it2){ - indices[index++] = it->first; - indices[index++] = *it2; - indices[index++] = -1; - } - } - - lines->coordIndex.finishEditing(); - Base::Console().Log(" NumEdges:%i\n",EdgeSize); - - Base::Console().Log(" %f: Finish =========================================================\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); - - -} +/*************************************************************************** + * Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderFemMesh.h" +#include "ViewProviderFemMeshPy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace FemGui; + + +struct FemFace +{ + const SMDS_MeshNode *Nodes[8]; + unsigned long ElementNumber; + const SMDS_MeshElement* Element; + unsigned short Size; + unsigned short FaceNo; + bool hide; + Base::Vector3d getFirstNodePoint(void) { + return Base::Vector3d(Nodes[0]->X(),Nodes[0]->Y(),Nodes[0]->Z()); + } + + Base::Vector3d set(short size,const SMDS_MeshElement* element,unsigned short id, short faceNo, + const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4=0, + const SMDS_MeshNode* n5=0,const SMDS_MeshNode* n6=0,const SMDS_MeshNode* n7=0,const SMDS_MeshNode* n8=0); + + bool isSameFace (FemFace &face); +}; + +Base::Vector3d FemFace::set(short size,const SMDS_MeshElement* element,unsigned short id,short faceNo, + const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4, + const SMDS_MeshNode* n5,const SMDS_MeshNode* n6,const SMDS_MeshNode* n7,const SMDS_MeshNode* n8) +{ + Nodes[0] = n1; + Nodes[1] = n2; + Nodes[2] = n3; + Nodes[3] = n4; + Nodes[4] = n5; + Nodes[5] = n6; + Nodes[6] = n7; + Nodes[7] = n8; + + Element = element; + ElementNumber = id; + Size = size; + FaceNo = faceNo; + hide = false; + + // sorting the nodes for later easier comparison (bubble sort) + int i, j, flag = 1; // set flag to 1 to start first pass + const SMDS_MeshNode* temp; // holding variable + + for(i = 1; (i <= size) && flag; i++) + { + flag = 0; + for (j=0; j < (size -1); j++) + { + if (Nodes[j+1] > Nodes[j]) // ascending order simply changes to < + { + temp = Nodes[j]; // swap elements + Nodes[j] = Nodes[j+1]; + Nodes[j+1] = temp; + flag = 1; // indicates that a swap occurred. + } + } + } + + return Base::Vector3d(Nodes[0]->X(),Nodes[0]->Y(),Nodes[0]->Z()); +} + +class FemFaceGridItem : public std::vector{ +public: + //FemFaceGridItem(void){reserve(200);} +}; + +bool FemFace::isSameFace (FemFace &face) +{ + // the same element can not have the same face + if(face.ElementNumber == ElementNumber) + return false; + if(face.Size != Size) + return false; + // if the same face size just compare if the sorted nodes are the same + if( Nodes[0] == face.Nodes[0] && + Nodes[1] == face.Nodes[1] && + Nodes[2] == face.Nodes[2] && + Nodes[3] == face.Nodes[3] && + Nodes[4] == face.Nodes[4] && + Nodes[5] == face.Nodes[5] && + Nodes[6] == face.Nodes[6] && + Nodes[7] == face.Nodes[7] ){ + hide = true; + face.hide = true; + return true; + } + + return false; +}; + +// ---------------------------------------------------------------------------- + +class ViewProviderFemMesh::Private +{ +public: + static const char *dm_face_wire; + static const char *dm_face_wire_node; + static const char *dm_face; + static const char *dm_node; + static const char *dm_wire; +}; + +const char * ViewProviderFemMesh::Private::dm_face_wire = "Faces & Wireframe"; +const char * ViewProviderFemMesh::Private::dm_face_wire_node = "Faces, Wireframe & Nodes"; +const char * ViewProviderFemMesh::Private::dm_face = "Faces"; +const char * ViewProviderFemMesh::Private::dm_node = "Nodes"; +const char * ViewProviderFemMesh::Private::dm_wire = "Wireframe"; + +PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject) + +App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0,64.0,1.0}; + +ViewProviderFemMesh::ViewProviderFemMesh() +{ + sPixmap = "fem-fem-mesh-from-shape"; + + ADD_PROPERTY(PointColor,(App::Color(0.7f,0.7f,0.7f))); + ADD_PROPERTY(PointSize,(5.0f)); + PointSize.setConstraints(&floatRange); + ADD_PROPERTY(LineWidth,(2.0f)); + LineWidth.setConstraints(&floatRange); + + ShapeColor.setValue(App::Color(1.0f,0.7f,0.0f)); + ADD_PROPERTY(BackfaceCulling,(true)); + ADD_PROPERTY(ShowInner, (false)); + + onlyEdges = false; + + pcDrawStyle = new SoDrawStyle(); + pcDrawStyle->ref(); + pcDrawStyle->style = SoDrawStyle::LINES; + pcDrawStyle->lineWidth = LineWidth.getValue(); + + pShapeHints = new SoShapeHints; + pShapeHints->shapeType = SoShapeHints::SOLID; + pShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; + pShapeHints->ref(); + + pcMatBinding = new SoMaterialBinding; + pcMatBinding->value = SoMaterialBinding::OVERALL; + pcMatBinding->ref(); + + pcCoords = new SoCoordinate3(); + pcCoords->ref(); + + pcAnoCoords = new SoCoordinate3(); + pcAnoCoords->ref(); + pcAnoCoords->point.setNum(0); + + pcFaces = new SoIndexedFaceSet; + pcFaces->ref(); + + pcLines = new SoIndexedLineSet; + pcLines->ref(); + + pcPointStyle = new SoDrawStyle(); + pcPointStyle->ref(); + pcPointStyle->style = SoDrawStyle::POINTS; + pcPointStyle->pointSize = PointSize.getValue(); + + pcPointMaterial = new SoMaterial; + pcPointMaterial->ref(); + //PointMaterial.touch(); + + DisplacementFactor = 0; +} + +ViewProviderFemMesh::~ViewProviderFemMesh() +{ + pcCoords->unref(); + pcDrawStyle->unref(); + pcFaces->unref(); + pcLines->unref(); + pShapeHints->unref(); + pcMatBinding->unref(); + pcPointMaterial->unref(); + pcPointStyle->unref(); + pcAnoCoords->unref(); +} + +void ViewProviderFemMesh::attach(App::DocumentObject *pcObj) +{ + ViewProviderGeometryObject::attach(pcObj); + + // Move 'coords' before the switch + //pcRoot->insertChild(pcCoords,pcRoot->findChild(reinterpret_cast(pcModeSwitch))); + + // Annotation sets + SoGroup* pcAnotRoot = new SoAnnotation(); + + SoDrawStyle *pcAnoStyle = new SoDrawStyle(); + pcAnoStyle->style = SoDrawStyle::POINTS; + pcAnoStyle->pointSize = 5; + + SoMaterial *pcAnoMaterial = new SoMaterial; + pcAnoMaterial->diffuseColor.setValue(0,1,0); + pcAnoMaterial->emissiveColor.setValue(0,1,0); + pcAnotRoot->addChild(pcAnoMaterial); + pcAnotRoot->addChild(pcAnoStyle); + pcAnotRoot->addChild(pcAnoCoords); + SoPointSet *pointset = new SoPointSet; + pcAnotRoot->addChild(pointset); + + // flat + SoGroup* pcFlatRoot = new SoGroup(); + // face nodes + pcFlatRoot->addChild(pcCoords); + pcFlatRoot->addChild(pShapeHints); + pcFlatRoot->addChild(pcShapeMaterial); + pcFlatRoot->addChild(pcMatBinding); + pcFlatRoot->addChild(pcFaces); + pcFlatRoot->addChild(pcAnotRoot); + addDisplayMaskMode(pcFlatRoot, Private::dm_face); + + // line + SoLightModel* pcLightModel = new SoLightModel(); + pcLightModel->model = SoLightModel::BASE_COLOR; + SoGroup* pcWireRoot = new SoGroup(); + pcWireRoot->addChild(pcCoords); + pcWireRoot->addChild(pcDrawStyle); + pcWireRoot->addChild(pcLightModel); + SoBaseColor* color = new SoBaseColor(); + color->rgb.setValue(0.0f,0.0f,0.0f); + pcWireRoot->addChild(color); + pcWireRoot->addChild(pcLines); + addDisplayMaskMode(pcWireRoot, Private::dm_wire); + + + // Points + SoGroup* pcPointsRoot = new SoSeparator(); + pcPointsRoot->addChild(pcPointMaterial); + pcPointsRoot->addChild(pcPointStyle); + pcPointsRoot->addChild(pcCoords); + pointset = new SoPointSet; + pcPointsRoot->addChild(pointset); + addDisplayMaskMode(pcPointsRoot, Private::dm_node); + + // flat+line (Elements) + SoPolygonOffset* offset = new SoPolygonOffset(); + offset->styles = SoPolygonOffset::LINES; + //offset->factor = 2.0f; + //offset->units = 1.0f; + SoGroup* pcFlatWireRoot = new SoSeparator(); + // add the complete flat group (contains the coordinates) + pcFlatWireRoot->addChild(pcFlatRoot); + //pcFlatWireRoot->addChild(offset); // makes no differents..... + // add the line nodes + SoMaterialBinding *pcMatBind = new SoMaterialBinding; + pcMatBind->value = SoMaterialBinding::OVERALL; + pcFlatWireRoot->addChild(pcMatBind); + pcFlatWireRoot->addChild(pcDrawStyle); + pcFlatWireRoot->addChild(pcLightModel); + pcFlatWireRoot->addChild(color); + pcFlatWireRoot->addChild(pcLines); + + addDisplayMaskMode(pcFlatWireRoot, Private::dm_face_wire); + + // flat+line+Nodes (Elements&Nodes) + SoGroup* pcElemNodesRoot = new SoSeparator(); + // add the complete flat group (contains the coordinates) + pcElemNodesRoot->addChild(pcFlatRoot); + //pcElemNodesRoot->addChild(offset); + // add the line nodes + pcElemNodesRoot->addChild(pcDrawStyle); + pcElemNodesRoot->addChild(pcLightModel); + pcElemNodesRoot->addChild(color); + pcElemNodesRoot->addChild(pcLines); + // add the points nodes + pcElemNodesRoot->addChild(pcPointMaterial); + pcElemNodesRoot->addChild(pcPointStyle); + pcElemNodesRoot->addChild(pcPointMaterial); + pcElemNodesRoot->addChild(pointset); + + addDisplayMaskMode(pcElemNodesRoot, Private::dm_face_wire_node); +} + +void ViewProviderFemMesh::setDisplayMode(const char* ModeName) +{ + setDisplayMaskMode(ModeName); + ViewProviderGeometryObject::setDisplayMode(ModeName); +} + +std::vector ViewProviderFemMesh::getDisplayModes(void) const +{ + std::vector StrList; + StrList.push_back(Private::dm_face_wire); + StrList.push_back(Private::dm_face_wire_node); + StrList.push_back(Private::dm_face); + StrList.push_back(Private::dm_wire); + StrList.push_back(Private::dm_node); + return StrList; +} + +void ViewProviderFemMesh::updateData(const App::Property* prop) +{ + if (prop->isDerivedFrom(Fem::PropertyFemMesh::getClassTypeId())) { + ViewProviderFEMMeshBuilder builder; + resetColorByNodeId(); + resetDisplacementByNodeId(); + builder.createMesh(prop, pcCoords, pcFaces, pcLines, vFaceElementIdx, vNodeElementIdx, onlyEdges, ShowInner.getValue()); + } + Gui::ViewProviderGeometryObject::updateData(prop); +} + +void ViewProviderFemMesh::onChanged(const App::Property* prop) +{ + if (prop == &PointSize) { + pcPointStyle->pointSize = PointSize.getValue(); + } + else if (prop == &PointColor) { + const App::Color& c = PointColor.getValue(); + pcPointMaterial->diffuseColor.setValue(c.r,c.g,c.b); + } + else if (prop == &BackfaceCulling) { + if(BackfaceCulling.getValue()){ + pShapeHints->shapeType = SoShapeHints::SOLID; + //pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE; + }else{ + pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; + //pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE; + } + } + else if (prop == &ShowInner ) { + // recalc mesh with new settings + ViewProviderFEMMeshBuilder builder; + builder.createMesh(&(dynamic_cast(this->pcObject)->FemMesh), pcCoords, pcFaces, pcLines, vFaceElementIdx, vNodeElementIdx, onlyEdges, ShowInner.getValue()); + } + else if (prop == &LineWidth) { + pcDrawStyle->lineWidth = LineWidth.getValue(); + } + else { + ViewProviderGeometryObject::onChanged(prop); + } +} + +std::string ViewProviderFemMesh::getElement(const SoDetail* detail) const +{ + std::stringstream str; + if (detail) { + if (detail->getTypeId() == SoFaceDetail::getClassTypeId()) { + const SoFaceDetail* face_detail = static_cast(detail); + unsigned long edx = vFaceElementIdx[face_detail->getFaceIndex()]; + + str << "Elem" << (edx>>3) << "F"<< (edx&7)+1; + } + // trigger on edges only if edge only mesh, otherwise you only hit edges an never faces.... + else if (onlyEdges && detail->getTypeId() == SoLineDetail::getClassTypeId()) { + const SoLineDetail* line_detail = static_cast(detail); + int edge = line_detail->getLineIndex() + 1; + str << "Edge" << edge; + } + else if (detail->getTypeId() == SoPointDetail::getClassTypeId()) { + const SoPointDetail* point_detail = static_cast(detail); + int idx = point_detail->getCoordinateIndex(); + if (idx < static_cast(vNodeElementIdx.size())) { + int vertex = vNodeElementIdx[point_detail->getCoordinateIndex()]; + str << "Node" << vertex; + } + else { + return std::string(); + } + } + } + + return str.str(); +} + +SoDetail* ViewProviderFemMesh::getDetail(const char* subelement) const +{ + std::string element = subelement; + std::string::size_type pos = element.find_first_of("0123456789"); + int index = -1; + if (pos != std::string::npos) { + index = std::atoi(element.substr(pos).c_str()); + element = element.substr(0,pos); + } + + SoDetail* detail = 0; + if (index < 0) + return detail; + if (element == "Elem") { + detail = new SoFaceDetail(); + static_cast(detail)->setPartIndex(index - 1); + } + //else if (element == "Edge") { + // detail = new SoLineDetail(); + // static_cast(detail)->setLineIndex(index - 1); + //} + //else if (element == "Vertex") { + // detail = new SoPointDetail(); + // static_cast(detail)->setCoordinateIndex(index + nodeset->startIndex.getValue() - 1); + //} + + return detail; +} + +std::vector ViewProviderFemMesh::getSelectionShape(const char* Element) const +{ + return std::vector(); +} + +void ViewProviderFemMesh::setHighlightNodes(const std::set& HighlightedNodes) +{ + if(!HighlightedNodes.empty()){ + SMESHDS_Mesh* data = const_cast((dynamic_cast(this->pcObject)->FemMesh).getValue().getSMesh())->GetMeshDS(); + + pcAnoCoords->point.setNum(HighlightedNodes.size()); + SbVec3f* verts = pcAnoCoords->point.startEditing(); + int i=0; + for(std::set::const_iterator it=HighlightedNodes.begin();it!=HighlightedNodes.end();++it,i++){ + const SMDS_MeshNode *Node = data->FindNode(*it); + if (Node) + verts[i].setValue((float)Node->X(),(float)Node->Y(),(float)Node->Z()); + else + verts[i].setValue(0,0,0); + } + pcAnoCoords->point.finishEditing(); + }else{ + pcAnoCoords->point.setNum(0); + } +} +void ViewProviderFemMesh::resetHighlightNodes(void) +{ + pcAnoCoords->point.setNum(0); +} + +PyObject * ViewProviderFemMesh::getPyObject() +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new ViewProviderFemMeshPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +void ViewProviderFemMesh::setColorByNodeId(const std::map &NodeColorMap) +{ + long startId = NodeColorMap.begin()->first; + long endId = (--NodeColorMap.end())->first; + + std::vector colorVec(endId-startId+2,App::Color(0,1,0)); + for(std::map::const_iterator it=NodeColorMap.begin();it!=NodeColorMap.end();++it) + colorVec[it->first-startId] = it->second; + + setColorByNodeIdHelper(colorVec); + +} +void ViewProviderFemMesh::setColorByNodeId(const std::vector &NodeIds,const std::vector &NodeColors) +{ + + long startId = *(std::min_element(NodeIds.begin(), NodeIds.end())); + long endId = *(std::max_element(NodeIds.begin(), NodeIds.end())); + + std::vector colorVec(endId-startId+2,App::Color(0,1,0)); + long i=0; + for(std::vector::const_iterator it=NodeIds.begin();it!=NodeIds.end();++it,i++) + colorVec[*it-startId] = NodeColors[i]; + + + setColorByNodeIdHelper(colorVec); + +} + +void ViewProviderFemMesh::setColorByNodeIdHelper(const std::vector &colorVec) +{ + pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; + + // resizing and writing the color vector: + pcShapeMaterial->diffuseColor.setNum(vNodeElementIdx.size()); + SbColor* colors = pcShapeMaterial->diffuseColor.startEditing(); + + long i=0; + for(std::vector::const_iterator it=vNodeElementIdx.begin() + ;it!=vNodeElementIdx.end() + ;++it,i++) + colors[i] = SbColor(colorVec[*it-1].r,colorVec[*it-1].g,colorVec[*it-1].b); + + + pcShapeMaterial->diffuseColor.finishEditing(); +} + +void ViewProviderFemMesh::resetColorByNodeId(void) +{ + pcMatBinding->value = SoMaterialBinding::OVERALL; + pcShapeMaterial->diffuseColor.setNum(0); + const App::Color& c = ShapeColor.getValue(); + pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b); + +} + +void ViewProviderFemMesh::setDisplacementByNodeId(const std::map &NodeDispMap) +{ + long startId = NodeDispMap.begin()->first; + long endId = (--NodeDispMap.end())->first; + + std::vector vecVec(endId-startId+2,Base::Vector3d()); + + for(std::map::const_iterator it=NodeDispMap.begin();it!=NodeDispMap.end();++it) + vecVec[it->first-startId] = it->second; + + setDisplacementByNodeIdHelper(vecVec,startId); +} + +void ViewProviderFemMesh::setDisplacementByNodeId(const std::vector &NodeIds,const std::vector &NodeDisps) +{ + long startId = *(std::min_element(NodeIds.begin(), NodeIds.end())); + long endId = *(std::max_element(NodeIds.begin(), NodeIds.end())); + + std::vector vecVec(endId-startId+2,Base::Vector3d()); + + long i=0; + for(std::vector::const_iterator it=NodeIds.begin();it!=NodeIds.end();++it,i++) + vecVec[*it-startId] = NodeDisps[i]; + + setDisplacementByNodeIdHelper(vecVec,startId); +} + +void ViewProviderFemMesh::setDisplacementByNodeIdHelper(const std::vector& DispVector,long startId) +{ + DisplacementVector.resize(vNodeElementIdx.size()); + int i=0; + for(std::vector::const_iterator it=vNodeElementIdx.begin();it!=vNodeElementIdx.end();++it,i++) + DisplacementVector[i] = DispVector[*it-startId]; + applyDisplacementToNodes(1.0); + +} + +void ViewProviderFemMesh::resetDisplacementByNodeId(void) +{ + applyDisplacementToNodes(0.0); + DisplacementVector.clear(); +} +/// reaply the node displacement with a certain factor and do a redraw +void ViewProviderFemMesh::applyDisplacementToNodes(double factor) +{ + if(DisplacementVector.size() == 0) + return; + + float x,y,z; + // set the point coordinates + long sz = pcCoords->point.getNum(); + SbVec3f* verts = pcCoords->point.startEditing(); + for (long i=0;i < sz ;i++) { + verts[i].getValue(x,y,z); + // undo old factor# + Base::Vector3d oldDisp = DisplacementVector[i] * DisplacementFactor; + x -= oldDisp.x; + y -= oldDisp.y; + z -= oldDisp.z; + // apply new factor + Base::Vector3d newDisp = DisplacementVector[i] * factor; + x += newDisp.x; + y += newDisp.y; + z += newDisp.z; + // set the new value + verts[i].setValue(x,y,z); + } + pcCoords->point.finishEditing(); + + DisplacementFactor = factor; +} + +void ViewProviderFemMesh::setColorByElementId(const std::map &ElementColorMap) +{ + pcMatBinding->value = SoMaterialBinding::PER_FACE ; + + // resizing and writing the color vector: + pcShapeMaterial->diffuseColor.setNum(vFaceElementIdx.size()); + SbColor* colors = pcShapeMaterial->diffuseColor.startEditing(); + + int i=0; + for(std::vector::const_iterator it=vFaceElementIdx.begin() + ;it!=vFaceElementIdx.end() + ;++it,i++){ + unsigned long ElemIdx = ((*it)>>3); + const std::map::const_iterator pos = ElementColorMap.find(ElemIdx); + if(pos == ElementColorMap.end()) + colors[i] = SbColor(0,1,0); + else + colors[i] = SbColor(pos->second.r,pos->second.g,pos->second.b); + } + + pcShapeMaterial->diffuseColor.finishEditing(); +} + +void ViewProviderFemMesh::resetColorByElementId(void) +{ + pcMatBinding->value = SoMaterialBinding::OVERALL; + pcShapeMaterial->diffuseColor.setNum(0); + const App::Color& c = ShapeColor.getValue(); + pcShapeMaterial->diffuseColor.setValue(c.r,c.g,c.b); + +} + +// ---------------------------------------------------------------------------- + +void ViewProviderFEMMeshBuilder::buildNodes(const App::Property* prop, std::vector& nodes) const +{ + SoCoordinate3 *pcPointsCoord=0; + SoIndexedFaceSet *pcFaces=0; + SoIndexedLineSet *pcLines=0; + + if (nodes.empty()) { + pcPointsCoord = new SoCoordinate3(); + nodes.push_back(pcPointsCoord); + pcFaces = new SoIndexedFaceSet(); + pcLines = new SoIndexedLineSet(); + nodes.push_back(pcFaces); + } + else if (nodes.size() == 2) { + if (nodes[0]->getTypeId() == SoCoordinate3::getClassTypeId()) + pcPointsCoord = static_cast(nodes[0]); + if (nodes[1]->getTypeId() == SoIndexedFaceSet::getClassTypeId()) + pcFaces = static_cast(nodes[1]); + } + + if (pcPointsCoord && pcFaces){ + std::vector vFaceElementIdx; + std::vector vNodeElementIdx; + bool onlyEdges; + createMesh(prop, pcPointsCoord, pcFaces,pcLines,vFaceElementIdx,vNodeElementIdx,onlyEdges,false); + } +} + +inline void insEdgeVec(std::map > &map, int n1, int n2) +{ + //FIXME: The if-else distinction doesn't make sense + //if (n1 &vFaceElementIdx, + std::vector &vNodeElementIdx, + bool &onlyEdges, + bool ShowInner) const +{ + + const Fem::PropertyFemMesh* mesh = static_cast(prop); + + SMESHDS_Mesh* data = const_cast(mesh->getValue().getSMesh())->GetMeshDS(); + + int numFaces = data->NbFaces(); + int numNodes = data->NbNodes(); + int numEdges = data->NbEdges(); + + if(numFaces+numNodes+numEdges == 0) return; + Base::TimeInfo Start; + Base::Console().Log("Start: ViewProviderFEMMeshBuilder::createMesh() =================================\n"); + + const SMDS_MeshInfo& info = data->GetMeshInfo(); + int numTria = info.NbTriangles(); + int numQuad = info.NbQuadrangles(); + + int numVolu = info.NbVolumes(); + int numTetr = info.NbTetras(); + int numHexa = info.NbHexas(); + int numPyrd = info.NbPyramids(); + int numPris = info.NbPrisms(); + + + bool ShowFaces = (numFaces >0 && numVolu == 0); + + int numTries; + if(ShowFaces) + numTries = numTria+numQuad/*+numPoly*/+numTetr*4+numHexa*6+numPyrd*5+numPris*5; + else + numTries = numTetr*4+numHexa*6+numPyrd*5+numPris*5; + // It is not 100% sure that a prism in smesh is a pentahedron in any case, but it will be in most cases! + // See http://forum.freecadweb.org/viewtopic.php?f=18&t=13583#p109707 + + // corner case only edges (Beams) in the mesh. This need some special cases in building up visual + onlyEdges = false; + if (numFaces <= 0 && numVolu <= 0 && numEdges > 0){ + onlyEdges = true; + } + + std::vector facesHelper(numTries); + + Base::Console().Log(" %f: Start build up %i face helper\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo()),facesHelper.size()); + Base::BoundBox3d BndBox; + + int i=0; + + if (ShowFaces){ + SMDS_FaceIteratorPtr aFaceIter = data->facesIterator(); + for (;aFaceIter->more();) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + + int num = aFace->NbNodes(); + switch(num){ + case 3: + //tria3 face = N1, N2, N3 + BndBox.Add(facesHelper[i++].set(3, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(1), aFace->GetNode(2))); + break; + case 4: + //quad4 face = N1, N2, N3, N4 + BndBox.Add(facesHelper[i++].set(4, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(1), aFace->GetNode(2), aFace->GetNode(3))); + break; + case 6: + //tria6 face = N1, N4, N2, N5, N3, N6 + BndBox.Add(facesHelper[i++].set(6, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(3), aFace->GetNode(1), aFace->GetNode(4), aFace->GetNode(2), aFace->GetNode(5))); + break; + case 8: + //quad8 face = N1, N5, N2, N6, N3, N7, N4, N8 + BndBox.Add(facesHelper[i++].set(8, aFace, aFace->GetID(), 0, aFace->GetNode(0), aFace->GetNode(4), aFace->GetNode(1), aFace->GetNode(5), aFace->GetNode(2), aFace->GetNode(6), aFace->GetNode(3), aFace->GetNode(7))); + break; + default: + //unknown face type + throw std::runtime_error("Node count not supported by ViewProviderFemMesh, [3|4|6|8] are allowed"); + } + } + } + else{ + + // iterate all volumes + SMDS_VolumeIteratorPtr aVolIter = data->volumesIterator(); + for (; aVolIter->more();) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + + int num = aVol->NbNodes(); + + switch (num){ + //tetra4 volume + case 4: + // face 1 = N1, N2, N3 + // face 2 = N1, N4, N2 + // face 3 = N2, N4, N3 + // face 4 = N3, N4, N1 + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(3), aVol->GetNode(1))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(3), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(3), aVol->GetNode(0))); + break; + //pyra5 volume + case 5: + // face 1 = N1, N2, N3, N4 + // face 2 = N1, N5, N2 + // face 3 = N2, N5, N3 + // face 4 = N3, N5, N4 + // face 5 = N4, N5, N1 + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2), aVol->GetNode(3))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(1))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(4), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(4), aVol->GetNode(3))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 5, aVol->GetNode(3), aVol->GetNode(4), aVol->GetNode(0))); + break; + //penta6 volume + case 6: + // face 1 = N1, N2, N3 + // face 2 = N4, N6, N5 + // face 3 = N1, N4, N5, N2 + // face 4 = N2, N5, N6, N3 + // face 5 = N3, N6, N4, N1 + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(3, aVol, aVol->GetID(), 2, aVol->GetNode(3), aVol->GetNode(5), aVol->GetNode(4))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(3), aVol->GetNode(4), aVol->GetNode(1))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(4), aVol->GetNode(5), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(5), aVol->GetNode(3), aVol->GetNode(0))); + break; + //hexa8 volume + case 8: + // face 1 = N1, N2, N3, N4 + // face 2 = N5, N8, N7, N6 + // face 3 = N1, N5, N6, N2 + // face 4 = N2, N6, N7, N3 + // face 5 = N3, N7, N8, N4 + // face 6 = N4, N8, N5, N1 + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(1), aVol->GetNode(2), aVol->GetNode(3))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 2, aVol->GetNode(4), aVol->GetNode(7), aVol->GetNode(6), aVol->GetNode(5))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(5), aVol->GetNode(1))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(5), aVol->GetNode(6), aVol->GetNode(2))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(6), aVol->GetNode(7), aVol->GetNode(3))); + BndBox.Add(facesHelper[i++].set(4, aVol, aVol->GetID(), 6, aVol->GetNode(3), aVol->GetNode(7), aVol->GetNode(4), aVol->GetNode(0))); + break; + //tetra10 volume + case 10: + // face 1 = N1, N5, N2, N6, N3, N7 + // face 2 = N1, N8, N4, N9, N2, N5 + // face 3 = N2, N9, N4, N10, N3, N6 + // face 4 = N3, N10, N4, N8, N1, N7 + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(4), aVol->GetNode(1), aVol->GetNode(5), aVol->GetNode(2), aVol->GetNode(6))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(7), aVol->GetNode(3), aVol->GetNode(8), aVol->GetNode(1), aVol->GetNode(4))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(8), aVol->GetNode(3), aVol->GetNode(9), aVol->GetNode(2), aVol->GetNode(5))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(9), aVol->GetNode(3), aVol->GetNode(7), aVol->GetNode(0), aVol->GetNode(6))); + break; + //pyra13 volume + case 13: + // face 1 = N1, N6, N2, N7, N3, N8, N4, N9 + // face 2 = N1, N10, N5, N11, N2, N6 + // face 3 = N2, N11, N5, N12, N3, N7 + // face 4 = N3, N12, N5, N13, N4, N8 + // face 5 = N4, N13, N5, N10, N1, N9 + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(5), aVol->GetNode(1), aVol->GetNode(6), aVol->GetNode(2), aVol->GetNode(7), aVol->GetNode(3), aVol->GetNode(8))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(0), aVol->GetNode(9), aVol->GetNode(4), aVol->GetNode(10), aVol->GetNode(1), aVol->GetNode(5))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 3, aVol->GetNode(1), aVol->GetNode(10), aVol->GetNode(4), aVol->GetNode(11), aVol->GetNode(2), aVol->GetNode(6))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 4, aVol->GetNode(2), aVol->GetNode(11), aVol->GetNode(4), aVol->GetNode(12), aVol->GetNode(3), aVol->GetNode(7))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 5, aVol->GetNode(3), aVol->GetNode(12), aVol->GetNode(4), aVol->GetNode(9), aVol->GetNode(0), aVol->GetNode(8))); + break; + //penta15 volume + case 15: + // face 1 = N1, N7, N2, N8, N3, N9 + // face 2 = N4, N12, N6, N11, N5, N10 + // face 3 = N1, N13, N4, N10, N5, N14, N2, N7 + // face 4 = N2, N14, N5, N11, N6, N15, N3, N8 + // face 5 = N3, N15, N6, N12, N4, N13, N1, N9 + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(6), aVol->GetNode(1), aVol->GetNode(7), aVol->GetNode(2), aVol->GetNode(8))); + BndBox.Add(facesHelper[i++].set(6, aVol, aVol->GetID(), 2, aVol->GetNode(3), aVol->GetNode(11), aVol->GetNode(5), aVol->GetNode(10), aVol->GetNode(4), aVol->GetNode(9))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(12), aVol->GetNode(3), aVol->GetNode(9), aVol->GetNode(4), aVol->GetNode(13), aVol->GetNode(1), aVol->GetNode(6))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(13), aVol->GetNode(4), aVol->GetNode(10), aVol->GetNode(5), aVol->GetNode(14), aVol->GetNode(2), aVol->GetNode(7))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(14), aVol->GetNode(5), aVol->GetNode(11), aVol->GetNode(3), aVol->GetNode(12), aVol->GetNode(0), aVol->GetNode(8))); + break; + //hexa20 volume + case 20: + // face 1 = N1, N9, N2, N10, N3, N11, N4, N12 + // face 2 = N5, N16, N8, N15, N7, N14, N6, N13 + // face 3 = N1, N17, N5, N13, N6, N18, N2, N9 + // face 4 = N2, N18, N6, N14, N7, N19, N3, N10 + // face 5 = N3, N19, N7, N15, N8, N20, N4, N11 + // face 6 = N4, N20, N8, N16, N5, N17, N1, N12 + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 1, aVol->GetNode(0), aVol->GetNode(8), aVol->GetNode(1), aVol->GetNode(9), aVol->GetNode(2), aVol->GetNode(10), aVol->GetNode(3), aVol->GetNode(11))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 2, aVol->GetNode(4), aVol->GetNode(15), aVol->GetNode(7), aVol->GetNode(14), aVol->GetNode(6), aVol->GetNode(13), aVol->GetNode(5), aVol->GetNode(12))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 3, aVol->GetNode(0), aVol->GetNode(16), aVol->GetNode(4), aVol->GetNode(12), aVol->GetNode(5), aVol->GetNode(17), aVol->GetNode(1), aVol->GetNode(8))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 4, aVol->GetNode(1), aVol->GetNode(17), aVol->GetNode(5), aVol->GetNode(13), aVol->GetNode(6), aVol->GetNode(18), aVol->GetNode(2), aVol->GetNode(9))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 5, aVol->GetNode(2), aVol->GetNode(18), aVol->GetNode(6), aVol->GetNode(14), aVol->GetNode(7), aVol->GetNode(19), aVol->GetNode(3), aVol->GetNode(10))); + BndBox.Add(facesHelper[i++].set(8, aVol, aVol->GetID(), 6, aVol->GetNode(3), aVol->GetNode(19), aVol->GetNode(7), aVol->GetNode(15), aVol->GetNode(4), aVol->GetNode(16), aVol->GetNode(0), aVol->GetNode(11))); + break; + //unknown volume type + default: + throw std::runtime_error("Node count not supported by ViewProviderFemMesh, [4|5|6|8|10|13|15|20] are allowed"); + } + } + } + int FaceSize = facesHelper.size(); + + + if( FaceSize < 5000){ + Base::Console().Log(" %f: Start eliminate internal faces SIMPLE\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + // search for double (inside) faces and hide them + if(!ShowInner){ + for(int l=0; l< FaceSize;l++){ + if(! facesHelper[l].hide){ + for(int i=l+1; i Grid(NbrX*NbrY*NbrZ); + + + unsigned int iX = 0; + unsigned int iY = 0; + unsigned int iZ = 0; + + for(int l=0; l< FaceSize;l++){ + Base::Vector3d point(facesHelper[l].getFirstNodePoint()); + double x = (point.x - Xmin) / Xln; + double y = (point.y - Ymin) / Yln; + double z = (point.z - Zmin) / Zln; + + iX = x; + iY = y; + iZ = z; + + if(iX >= NbrX || iY >= NbrY || iZ >= NbrZ) + Base::Console().Log(" Outof range!\n"); + + Grid[iX + iY*NbrX + iZ*NbrX*NbrY].push_back(&facesHelper[l]); + } + + unsigned int max =0, avg = 0; + for(std::vector::iterator it=Grid.begin();it!=Grid.end();++it){ + for(unsigned int l=0; l< it->size();l++){ + if(! it->operator[](l)->hide){ + for(unsigned int i=l+1; isize(); i++){ + if(it->operator[](l)->isSameFace(*(it->operator[](i))) ){ + break; + } + } + } + } + if(it->size() > max)max=it->size(); + avg += it->size(); + } + avg = avg/Grid.size(); + + Base::Console().Log(" VoxelSize: Max:%i ,Average:%i\n",max,avg); + + } //if( FaceSize < 1000) + + + Base::Console().Log(" %f: Start build up node map\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + // sort out double nodes and build up index map + std::map mapNodeIndex; + + // handling the corner case beams only, means no faces/triangles only nodes and edges + if (onlyEdges){ + + SMDS_EdgeIteratorPtr aEdgeIte = data->edgesIterator(); + for (; aEdgeIte->more();) { + const SMDS_MeshEdge* aEdge = aEdgeIte->next(); + int num = aEdge->NbNodes(); + for (int i = 0; i < num; i++) { + mapNodeIndex[aEdge->GetNode(i)] = 0; + + } + } + }else{ + + for (int l = 0; l < FaceSize; l++) { + if (!facesHelper[l].hide) { + for (int i = 0; i < 8; i++) { + if (facesHelper[l].Nodes[i]) + mapNodeIndex[facesHelper[l].Nodes[i]] = 0; + else + break; + } + } + } + } + Base::Console().Log(" %f: Start set point vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + // set the point coordinates + coords->point.setNum(mapNodeIndex.size()); + vNodeElementIdx.resize(mapNodeIndex.size() ); + std::map::iterator it= mapNodeIndex.begin(); + SbVec3f* verts = coords->point.startEditing(); + for (int i=0;it != mapNodeIndex.end() ;++it,i++) { + verts[i].setValue((float)it->first->X(),(float)it->first->Y(),(float)it->first->Z()); + it->second = i; + // set selection idx + vNodeElementIdx[i] = it->first->GetID(); + } + coords->point.finishEditing(); + + + + // count triangle size + Base::Console().Log(" %f: Start count triangle size\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + int triangleCount=0; + for (int l = 0; l < FaceSize; l++){ + if (!facesHelper[l].hide) + switch (facesHelper[l].Size){ + case 3:triangleCount++; break; // 3-node triangle face --> 1 triangle + case 4:triangleCount += 2; break; // 4-node quadrangle face --> 2 triangles + case 6:triangleCount += 4; break; // 6-node triangle face --> 4 triangles + case 8:triangleCount += 6; break; // 8-node quadrangle face --> 6 triangles + default: throw std::runtime_error("Face with unknown node count found, only display mode nodes is supported for this element (tiangleCount)"); + } + } + Base::Console().Log(" NumTriangles:%i\n",triangleCount); + // edge map collect and sort edges of the faces to be shown. + std::map > EdgeMap; + + // handling the corner case beams only, means no faces/triangles only nodes and edges + if (onlyEdges){ + + SMDS_EdgeIteratorPtr aEdgeIte = data->edgesIterator(); + for (; aEdgeIte->more();) { + const SMDS_MeshEdge* aEdge = aEdgeIte->next(); + int num = aEdge->NbNodes(); + switch (num){ + case 2: { // Seg2: N1, N2 + int nIdx0 = mapNodeIndex[aEdge->GetNode(0)]; + int nIdx1 = mapNodeIndex[aEdge->GetNode(1)]; + insEdgeVec(EdgeMap, nIdx0, nIdx1); + break; + } + + case 3: { // Seg3: N1, N2, N3 (N3 is middle Node) + int nIdx0 = mapNodeIndex[aEdge->GetNode(0)]; + int nIdx1 = mapNodeIndex[aEdge->GetNode(1)]; + int nIdx2 = mapNodeIndex[aEdge->GetNode(2)]; + insEdgeVec(EdgeMap, nIdx0, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx1); + break; + } + } + } + } + + Base::Console().Log(" %f: Start build up triangle vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + // set the triangle face indices + faces->coordIndex.setNum(4*triangleCount); + vFaceElementIdx.resize(triangleCount); + int index=0,indexIdx=0; + int32_t* indices = faces->coordIndex.startEditing(); + // iterate all not hided element faces, allways assure CLOCKWISE triangle ordering to allow backface culling + for(int l=0; l< FaceSize;l++){ + if(! facesHelper[l].hide){ + switch( facesHelper[l].Element->NbNodes()){ + // 3 nodes + case 3: + // tria3 face + switch (facesHelper[l].FaceNo){ + case 0: { // tria3 face, 3-node triangle + // prefeche all node indexes of this face + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + // create triangle number 1 ---------------------------------------------- + // fill in the node indexes in CLOCKWISE order + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + // add the three edge segments for that triangle + insEdgeVec(EdgeMap, nIdx0, nIdx1); + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx0); + // rember the element and face number for that triangle + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + default: assert(0); + } + break; + // 4 nodes + case 4: + // quad4 face + // tetra4 volume, four 3-node triangles + switch (facesHelper[l].FaceNo){ + case 0: { // quad4 face, 4-node quadrangle + // prefeche all node indexes of this face + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + // create triangle number 1 ---------------------------------------------- + // fill in the node indexes in CLOCKWISE order + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + // add the two edge segments for that triangle + insEdgeVec(EdgeMap, nIdx0, nIdx1); + insEdgeVec(EdgeMap, nIdx1, nIdx2); + // rember the element and face number for that triangle + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 2 ---------------------------------------------- + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx2, nIdx3); + insEdgeVec(EdgeMap, nIdx3, nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + case 1: { // tetra4 volume: face 1, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + case 2: { // tetra4 volume: face 2, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + break; } + case 3: { // tetra4 volume: face 3, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + break; } + case 4: { // tetra4 volume: face 4, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + break; } + default: assert(0); + } + break; + // 5 nodes + case 5: + // pyra5 volume, one 4-node quadrangle and four 3-node triangles + switch (facesHelper[l].FaceNo){ + case 1: { // pyra5 volume: face 1, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + case 2: { // pyra5 volume: face 2, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + break; } + case 3: { // pyra5 volume: face 3, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + break; } + case 4: { // pyra5 volume: face 4, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + break; } + case 5: { // pyra5 volume: face 5, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + break; } + default: assert(0); + } + break; + // 6 nodes + case 6: + // tria6 face + // penta6 volume, two 3-node triangle and three 4-node qudrangles + switch (facesHelper[l].FaceNo){ + case 0: { // tria6 face, 6-node triangle + // prefeche all node indexes of this face + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + // create triangle number 1 ---------------------------------------------- + // fill in the node indexes in CLOCKWISE order + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + // add the two edge segments for that triangle + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + // rember the element and face number for that triangle + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 2 ---------------------------------------------- + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 3 ---------------------------------------------- + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 4 ---------------------------------------------- + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + // this triangle has no edge (inner triangle). + break; } + case 1: { // penta6 volume: face 1, 3-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + insEdgeVec(EdgeMap,nIdx2,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + case 2: { // penta6 volume: face 2, 3-node triangle + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx4; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx3,nIdx5); + insEdgeVec(EdgeMap,nIdx5,nIdx4); + insEdgeVec(EdgeMap,nIdx4,nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + break; } + case 3: { // penta6 volume: face 3, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + break; } + case 4: { // penta6 volume: face 4, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + break; } + case 5: { // penta6 volume: face 5, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + break; } + default: assert(0); + } + break; + // 8 nodes + case 8: + // quad8 face + // hexa8 volume, six 4-node quadrangles + switch(facesHelper[l].FaceNo){ + case 0: { // quad8 face, 8-node quadrangle + // prefeche all node indexes of this face + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + // create triangle number 1 ---------------------------------------------- + // fill in the node indexes in CLOCKWISE order + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + // add the two edge segments for that triangle + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + // rember the element and face number for that triangle + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 2 ---------------------------------------------- + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 3 ---------------------------------------------- + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 4 ---------------------------------------------- + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + // create triangle number 5 ---------------------------------------------- + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + // this triangle has no edge (inner triangle) + // create triangle number 6 ---------------------------------------------- + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + // this triangle has no edge (inner triangle) + break; } + case 1: { // hexa8 volume: face 1, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + break; } + case 2: { // hexa8 volume: face 2, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + break; } + case 3: { // hexa8 volume: face 3, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + break; } + case 4: { // hexa8 volume: face 4, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + break; } + case 5: { // hexa8 volume: face 5, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + break; } + case 6: { // hexa8 volume: face 6, 4-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx0,nIdx1); + insEdgeVec(EdgeMap,nIdx1,nIdx2); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = nIdx0; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap,nIdx2,nIdx3); + insEdgeVec(EdgeMap,nIdx3,nIdx0); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + break; } + default: assert(0); + } + break; + // 10 nodes + case 10: + // tetra10 volume, four 6-node triangles + switch(facesHelper[l].FaceNo){ + case 1: { // tetra10 volume: face 1, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 2: { // tetra10 volume: face 2, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 3: { // tetra10 volume: face 3, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 4: { // tetra10 volume: face 4, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + default: assert(0); + } + break; + // 13 nodes + case 13: + // pyra13 volume, four 6-node triangle and one 8-node qudrangles + switch(facesHelper[l].FaceNo){ + case 1: { // pyra13 volume: face 1, 8-node qudrangles + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber, 0); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 2: { // pyra13 volume: face 2, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 3: { // pyra13 volume: face 3, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 4: { // pyra13 volume: face 4, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 5: { // pyra13 volume: face 5, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + default: assert(0); + } + break; + // 15 nodes + case 15: + // penta15 volume, two 6-node triangles and three 8-node qudrangles + switch(facesHelper[l].FaceNo){ + case 1: { // penta15 volume: face 1, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 2: { // penta15 volume: face 2, 6-node triangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + indices[index++] = nIdx5; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 3: { // penta15 volume: face 3, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 4: { // penta15 volume: face 4, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 5: { // penta15 volume: face 5, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + default: assert(0); + } + break; + // 20 nodes + case 20: + // hexa20 volume, six 8-node qudrangles + switch(facesHelper[l].FaceNo){ + case 1: { // hexa20 volume: face 1 + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,0); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 2: { // hexa20 volume: face 2, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(15)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,1); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 3: { // hexa20 volume: face 3, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(16)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(12)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(17)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(8)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,2); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 4: { // hexa20 volume: face 4, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(1)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(17)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(5)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(13)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(18)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(9)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,3); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 5: { // hexa20 volume: face 5, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(2)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(18)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(6)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(14)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(19)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(10)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,4); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + case 6: { // hexa20 volume: face 6, 8-node quadrangle + int nIdx0 = mapNodeIndex[facesHelper[l].Element->GetNode(3)]; + int nIdx1 = mapNodeIndex[facesHelper[l].Element->GetNode(19)]; + int nIdx2 = mapNodeIndex[facesHelper[l].Element->GetNode(7)]; + int nIdx3 = mapNodeIndex[facesHelper[l].Element->GetNode(15)]; + int nIdx4 = mapNodeIndex[facesHelper[l].Element->GetNode(4)]; + int nIdx5 = mapNodeIndex[facesHelper[l].Element->GetNode(16)]; + int nIdx6 = mapNodeIndex[facesHelper[l].Element->GetNode(0)]; + int nIdx7 = mapNodeIndex[facesHelper[l].Element->GetNode(11)]; + indices[index++] = nIdx7; + indices[index++] = nIdx0; + indices[index++] = nIdx1; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx7, nIdx0); + insEdgeVec(EdgeMap, nIdx0, nIdx1); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + indices[index++] = nIdx1; + indices[index++] = nIdx2; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx1, nIdx2); + insEdgeVec(EdgeMap, nIdx2, nIdx3); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + indices[index++] = nIdx3; + indices[index++] = nIdx4; + indices[index++] = nIdx5; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx3, nIdx4); + insEdgeVec(EdgeMap, nIdx4, nIdx5); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + indices[index++] = nIdx5; + indices[index++] = nIdx6; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + insEdgeVec(EdgeMap, nIdx5, nIdx6); + insEdgeVec(EdgeMap, nIdx6, nIdx7); + vFaceElementIdx[indexIdx++] = ElemFold(facesHelper[l].ElementNumber,5); + indices[index++] = nIdx7; + indices[index++] = nIdx1; + indices[index++] = nIdx3; + indices[index++] = SO_END_FACE_INDEX; + indices[index++] = nIdx3; + indices[index++] = nIdx5; + indices[index++] = nIdx7; + indices[index++] = SO_END_FACE_INDEX; + break; } + default: assert(0); + } + break; + + // not implemented elements + default: throw std::runtime_error("Element with unknown node count found (may be not implemented), only display mode nodes is supported for this element (NodeCount)"); + } + } + } + + faces->coordIndex.finishEditing(); + + Base::Console().Log(" %f: Start build up edge vector\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + // std::map > EdgeMap; + // count edges + int EdgeSize = 0; + for(std::map >::const_iterator it= EdgeMap.begin();it!= EdgeMap.end();++it) + EdgeSize += it->second.size(); + + // set the triangle face indices + lines->coordIndex.setNum(3*EdgeSize); + index=0; + indices = lines->coordIndex.startEditing(); + + for(std::map >::const_iterator it= EdgeMap.begin();it!= EdgeMap.end();++it){ + for(std::set::const_iterator it2=it->second.begin();it2!=it->second.end();++it2){ + indices[index++] = it->first; + indices[index++] = *it2; + indices[index++] = -1; + } + } + + lines->coordIndex.finishEditing(); + Base::Console().Log(" NumEdges:%i\n",EdgeSize); + + Base::Console().Log(" %f: Finish =========================================================\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemMesh.h b/src/Mod/Fem/Gui/ViewProviderFemMesh.h index 7f18eab8c105..042414328a37 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMesh.h +++ b/src/Mod/Fem/Gui/ViewProviderFemMesh.h @@ -1,169 +1,169 @@ -/*************************************************************************** - * Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef FEM_VIEWPROVIDERFEMMESH_H -#define FEM_VIEWPROVIDERFEMMESH_H - -#include -#include - -#include - -class SoCoordinate3; -class SoDrawStyle; -class SoIndexedFaceSet; -class SoIndexedLineSet; -class SoShapeHints; -class SoMaterialBinding; - -namespace FemGui -{ - -class ViewProviderFEMMeshBuilder : public Gui::ViewProviderBuilder -{ -public: - ViewProviderFEMMeshBuilder(){} - virtual ~ViewProviderFEMMeshBuilder(){} - virtual void buildNodes(const App::Property*, std::vector&) const; - void createMesh(const App::Property*, - SoCoordinate3*, - SoIndexedFaceSet*, - SoIndexedLineSet*, - std::vector&, - std::vector&, - bool &edgeOnly, - bool ShowInner - ) const; -}; - -class FemGuiExport ViewProviderFemMesh : public Gui::ViewProviderGeometryObject -{ - PROPERTY_HEADER(FemGui::ViewProviderFemMesh); - -public: - /// constructor. - ViewProviderFemMesh(); - - /// destructor. - virtual ~ViewProviderFemMesh(); - - // Display properties - App::PropertyColor PointColor; - App::PropertyFloatConstraint PointSize; - App::PropertyFloatConstraint LineWidth; - App::PropertyBool BackfaceCulling; - App::PropertyBool ShowInner; - - void attach(App::DocumentObject *pcObject); - void setDisplayMode(const char* ModeName); - std::vector getDisplayModes() const; +/*************************************************************************** + * Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_VIEWPROVIDERFEMMESH_H +#define FEM_VIEWPROVIDERFEMMESH_H + +#include +#include + +#include + +class SoCoordinate3; +class SoDrawStyle; +class SoIndexedFaceSet; +class SoIndexedLineSet; +class SoShapeHints; +class SoMaterialBinding; + +namespace FemGui +{ + +class ViewProviderFEMMeshBuilder : public Gui::ViewProviderBuilder +{ +public: + ViewProviderFEMMeshBuilder(){} + virtual ~ViewProviderFEMMeshBuilder(){} + virtual void buildNodes(const App::Property*, std::vector&) const; + void createMesh(const App::Property*, + SoCoordinate3*, + SoIndexedFaceSet*, + SoIndexedLineSet*, + std::vector&, + std::vector&, + bool &edgeOnly, + bool ShowInner + ) const; +}; + +class FemGuiExport ViewProviderFemMesh : public Gui::ViewProviderGeometryObject +{ + PROPERTY_HEADER(FemGui::ViewProviderFemMesh); + +public: + /// constructor. + ViewProviderFemMesh(); + + /// destructor. + virtual ~ViewProviderFemMesh(); + + // Display properties + App::PropertyColor PointColor; + App::PropertyFloatConstraint PointSize; + App::PropertyFloatConstraint LineWidth; + App::PropertyBool BackfaceCulling; + App::PropertyBool ShowInner; + + void attach(App::DocumentObject *pcObject); + void setDisplayMode(const char* ModeName); + std::vector getDisplayModes() const; void updateData(const App::Property*); - /** @name Selection handling - * This group of methodes do the selection handling. - * Here you can define how the selection for your ViewProvider - * works. - */ - //@{ - /// indicates if the ViewProvider use the new Selection model - virtual bool useNewSelectionModel(void) const {return true;} - /// return a hit element to the selection path or 0 - virtual std::string getElement(const SoDetail*) const; - virtual SoDetail* getDetail(const char*) const; - /// return the higlight lines for a given element or the whole shape - virtual std::vector getSelectionShape(const char* Element) const; - //@} + /** @name Selection handling + * This group of methodes do the selection handling. + * Here you can define how the selection for your ViewProvider + * works. + */ + //@{ + /// indicates if the ViewProvider use the new Selection model + virtual bool useNewSelectionModel(void) const {return true;} + /// return a hit element to the selection path or 0 + virtual std::string getElement(const SoDetail*) const; + virtual SoDetail* getDetail(const char*) const; + /// return the higlight lines for a given element or the whole shape + virtual std::vector getSelectionShape(const char* Element) const; + //@} // interface methodes void setHighlightNodes(const std::set&); void resetHighlightNodes(void); - - /** @name Postprocessing - * this interfaces apply post processing stuff to the View- - * Provider. They can override the positioning and the color - * color or certain elements. - */ - //@{ - - /// set the color for each node - void setColorByNodeId(const std::map &NodeColorMap); - void setColorByNodeId(const std::vector &NodeIds,const std::vector &NodeColors); - + + /** @name Postprocessing + * this interfaces apply post processing stuff to the View- + * Provider. They can override the positioning and the color + * color or certain elements. + */ + //@{ + + /// set the color for each node + void setColorByNodeId(const std::map &NodeColorMap); + void setColorByNodeId(const std::vector &NodeIds,const std::vector &NodeColors); + /// reset the view of the node colors void resetColorByNodeId(void); - /// set the displacement for each node - void setDisplacementByNodeId(const std::map &NodeDispMap); - void setDisplacementByNodeId(const std::vector &NodeIds,const std::vector &NodeDisps); + /// set the displacement for each node + void setDisplacementByNodeId(const std::map &NodeDispMap); + void setDisplacementByNodeId(const std::vector &NodeIds,const std::vector &NodeDisps); /// reset the view of the node displacement void resetDisplacementByNodeId(void); /// reaply the node displacement with a certain factor and do a redraw void applyDisplacementToNodes(double factor); - /// set the color for each element - void setColorByElementId(const std::map &ElementColorMap); + /// set the color for each element + void setColorByElementId(const std::map &ElementColorMap); /// reset the view of the element colors void resetColorByElementId(void); //@} const std::vector &getVisibleElementFaces(void)const{return vFaceElementIdx;} - PyObject *getPyObject(); + PyObject *getPyObject(); private: - static App::PropertyFloatConstraint::Constraints floatRange; - - Py::Object PythonObject; + static App::PropertyFloatConstraint::Constraints floatRange; + + Py::Object PythonObject; protected: - /// get called by the container whenever a property has been changed - virtual void onChanged(const App::Property* prop); - - void setColorByNodeIdHelper(const std::vector &); - void setDisplacementByNodeIdHelper(const std::vector& DispVector,long startId); - /// index of elements to their triangles - std::vector vFaceElementIdx; - std::vector vNodeElementIdx; - - std::vector DisplacementVector; - double DisplacementFactor; - - SoMaterial * pcPointMaterial; - SoDrawStyle * pcPointStyle; - - SoDrawStyle * pcDrawStyle; - SoShapeHints * pShapeHints; - SoMaterialBinding * pcMatBinding; - SoCoordinate3 * pcCoords; - SoCoordinate3 * pcAnoCoords; - SoIndexedFaceSet * pcFaces; - SoIndexedLineSet * pcLines; - - bool onlyEdges; - -private: - class Private; -}; - -} //namespace FemGui - - -#endif // FEM_VIEWPROVIDERFEMMESH_H + /// get called by the container whenever a property has been changed + virtual void onChanged(const App::Property* prop); + + void setColorByNodeIdHelper(const std::vector &); + void setDisplacementByNodeIdHelper(const std::vector& DispVector,long startId); + /// index of elements to their triangles + std::vector vFaceElementIdx; + std::vector vNodeElementIdx; + + std::vector DisplacementVector; + double DisplacementFactor; + + SoMaterial * pcPointMaterial; + SoDrawStyle * pcPointStyle; + + SoDrawStyle * pcDrawStyle; + SoShapeHints * pShapeHints; + SoMaterialBinding * pcMatBinding; + SoCoordinate3 * pcCoords; + SoCoordinate3 * pcAnoCoords; + SoIndexedFaceSet * pcFaces; + SoIndexedLineSet * pcLines; + + bool onlyEdges; + +private: + class Private; +}; + +} //namespace FemGui + + +#endif // FEM_VIEWPROVIDERFEMMESH_H diff --git a/src/Mod/Fem/Gui/Workbench.h b/src/Mod/Fem/Gui/Workbench.h index 7fbc41e3e139..aee7c353560b 100755 --- a/src/Mod/Fem/Gui/Workbench.h +++ b/src/Mod/Fem/Gui/Workbench.h @@ -1,50 +1,50 @@ -/*************************************************************************** - * Copyright (c) 2008 Werner Mayer * - * * - * 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 * - * * - ***************************************************************************/ - - -#ifndef IMAGE_WORKBENCH_H -#define IMAGE_WORKBENCH_H - -#include - -namespace FemGui { - -/** - * @author Werner Mayer - */ -class FemGuiExport Workbench : public Gui::StdWorkbench -{ - TYPESYSTEM_HEADER(); - -public: - Workbench(); - virtual ~Workbench(); - -protected: - Gui::ToolBarItem* setupToolBars() const; - Gui::MenuItem* setupMenuBar() const; -}; - -} // namespace FemGui - - -#endif // IMAGE_WORKBENCH_H +/*************************************************************************** + * Copyright (c) 2008 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef IMAGE_WORKBENCH_H +#define IMAGE_WORKBENCH_H + +#include + +namespace FemGui { + +/** + * @author Werner Mayer + */ +class FemGuiExport Workbench : public Gui::StdWorkbench +{ + TYPESYSTEM_HEADER(); + +public: + Workbench(); + virtual ~Workbench(); + +protected: + Gui::ToolBarItem* setupToolBars() const; + Gui::MenuItem* setupMenuBar() const; +}; + +} // namespace FemGui + + +#endif // IMAGE_WORKBENCH_H