[Assembly] remove it

as discussed: https://forum.freecadweb.org/viewtopic.php?p=582152#p582152
This commit is contained in:
Uwe
2022-03-22 17:51:06 +01:00
parent 802aa53aa1
commit 245f5b6c7d
255 changed files with 0 additions and 45200 deletions

View File

@@ -81,7 +81,6 @@ if(DOXYGEN_FOUND)
set( DOXYGEN_EXCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/Tools)
list(APPEND DOXYGEN_EXCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/Doc/sphinx)
# deprecated modules
list(APPEND DOXYGEN_EXCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/Mod/Assembly)
list(APPEND DOXYGEN_EXCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/Mod/Complete)
STRING(REGEX REPLACE ";" " " DOXYGEN_EXCLUDE_LIST "${DOXYGEN_EXCLUDE_DIR}")

View File

@@ -1,81 +0,0 @@
/***************************************************************************
* 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"
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include "Item.h"
#include "Product.h"
#include "ProductRef.h"
#include "Constraint.h"
#include "ConstraintGroup.h"
extern struct PyMethodDef Assembly_methods[];
PyDoc_STRVAR(module_Assembly_doc,
"This module is the Assembly module.");
/* Python entry */
extern "C" {
void AssemblyExport initAssembly()
{
// load dependent module
try {
Base::Interpreter().runString("import Part");
//Base::Interpreter().runString("import PartDesign");
}
catch(const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return;
}
static struct PyModuleDef AssemblyAPIDef = {
PyModuleDef_HEAD_INIT,
"Assembly", module_Assembly_doc, -1, Assembly_methods,
NULL, NULL, NULL, NULL
};
PyModule_Create(&AssemblyAPIDef);
Base::Console().Log("Loading Assembly module... done\n");
//dWorldID id = dWorldCreate();
//dWorldDestroy(id);
// 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.
// Item hierarchy
Assembly::Item ::init();
Assembly::Product ::init();
Assembly::ProductRef ::init();
// constraint hierarchy
Assembly::Constraint ::init();
Assembly::ConstraintGroup ::init();
}
} // extern "C"

View File

@@ -1,87 +0,0 @@
/***************************************************************************
* 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"
#include <Base/PyObjectBase.h>
#include <Base/Console.h>
//#include <App/PartPy.h>
//#include <Gui/Application.h>
//#include <Gui/Document.h>
//#include <Gui/ViewProviderDocumentObject.h>
//#include <Mod/PartDesign/App/BodyPy.h>
//#include "ViewProviderBody.h"
//#include "Utils.h"
//static PyObject * setActiveBody(PyObject *self, PyObject *args)
//{
// PyObject *object=0;
// if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) {
// PartDesign::Body* Item = static_cast<PartDesign::BodyPy*>(object)->getBodyPtr();
// // Should be set!
// assert(Item);
//
// // Set old body inactive if we are activating another body in the same document
// if ((PartDesignGui::ActivePartObject != NULL) &&
// (PartDesignGui::ActivePartObject->getDocument() == Item->getDocument()))
// PartDesignGui::ActivePartObject->IsActive.setValue(false);
// PartDesignGui::ActivePartObject = Item;
// PartDesignGui::ActiveAppDoc = Item->getDocument();
// PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc);
// PartDesignGui::ActiveVp = dynamic_cast<Gui::ViewProviderDocumentObject*> (PartDesignGui::ActiveGuiDoc->getViewProvider(Item));
// PartDesignGui::ActiveVp->show();
// Item->IsActive.setValue(true);
// } else {
// // This handles the case of deactivating the workbench
// PartDesignGui::ActivePartObject=0;
// PartDesignGui::ActiveGuiDoc =0;
// PartDesignGui::ActiveAppDoc =0;
// PartDesignGui::ActiveVp =0;
// }
//
// Py_Return;
//}
//
//static PyObject * getActiveBody(PyObject *, PyObject *)
//{
// if (PartDesignGui::ActivePartObject == NULL) {
// return Py::_None();
// }
//
// return PartDesignGui::ActivePartObject->getPyObject();
//}
/* registration table */
struct PyMethodDef Assembly_methods[] = {
//{"setActiveBody" ,setActiveBody ,METH_VARARGS,
// "setActiveBody(BodyObject) -- Set the PartBody object in work."},
//{"getActiveBody" ,getActiveBody ,METH_NOARGS,
// "getActiveBody() -- Get the PartBody object in work."},
{NULL, NULL} /* end of table marker */
};

View File

@@ -1,124 +0,0 @@
if(MSVC)
add_definitions(-DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH)
else(MSVC)
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
endif(MSVC)
add_definitions(-DBOOST_${Boost_VERSION})
include_directories(
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
${CMAKE_SOURCE_DIR}/src/Mod/Assembly/App
${CMAKE_CURRENT_BINARY_DIR}
${Boost_INCLUDE_DIRS}
${OCC_INCLUDE_DIR}
${PYTHON_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
#${ODE_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR}
)
link_directories(${OCC_LIBRARY_DIR})
set(Assembly_LIBS
#${ODE_LIBRARIES}
${OCC_LIBRARIES}
${Boost_LIBRARIES}
${Boost_LOG_LIBRARY_RELEASE}
Part
FreeCADApp
)
generate_from_xml(ItemPy)
generate_from_xml(ProductRefPy)
#generate_from_xml(PartRefPy)
generate_from_xml(ConstraintPy)
generate_from_xml(ConstraintGroupPy)
SET(Features_SRCS
Item.cpp
Item.h
#PartRef.cpp
#PartRef.h
Product.cpp
Product.h
ProductRef.cpp
ProductRef.h
Constraint.cpp
Constraint.h
ConstraintGroup.cpp
ConstraintGroup.h
)
SOURCE_GROUP("Features" FILES ${Features_SRCS})
SET(Module_SRCS
AppAssembly.cpp
AppAssemblyPy.cpp
PreCompiled.cpp
PreCompiled.h
)
SOURCE_GROUP("Module" FILES ${Module_SRCS})
#externalization is not possible for msvc as a stupid bug prevents the function definition resolving
if(MSVC)
set(Solver_SRC )
else(MSVC)
set(Solver_SRC Solver/solver_3d_ext1.cpp
Solver/solver_3d_ext2.cpp
Solver/solver_3d_ext3.cpp
)
if(FREECAD_ASSEMBLY_DEBUG_FACILITIES)
set(Solver_SRC ${Solver_SRC}
Solver/solver_state_ext1.cpp
Solver/solver_state_ext2.cpp
)
endif(FREECAD_ASSEMBLY_DEBUG_FACILITIES)
endif(MSVC)
SOURCE_GROUP("Solver" FILES ${Solver_SRC})
SET(Python_SRCS
ItemPy.xml
ItemPyImp.cpp
ProductRefPy.xml
ProductRefPyImp.cpp
#PartRefPy.xml
#PartRefPyImp.cpp
ConstraintPy.xml
ConstraintPyImp.cpp
ConstraintGroupPy.xml
ConstraintGroupPyImp.cpp
)
SOURCE_GROUP("Python" FILES ${Python_SRCS})
SET(Assembly_SRCS
${Features_SRCS}
${Python_SRCS}
${Module_SRCS}
${Solver_SRC}
)
SET(Assembly_Scripts
../Init.py
../AssemblyLib.py
)
add_library(Assembly SHARED ${Assembly_SRCS} ${Assembly_Scripts})
if(CMAKE_COMPILER_IS_GNUCXX)
set_target_properties(Assembly PROPERTIES COMPILE_FLAGS "-fext-numeric-literals")
endif()
target_link_libraries(Assembly ${Assembly_LIBS} ${log_LIB})
fc_target_copy_resource_flat(Assembly
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR}/Mod/Assembly
${Assembly_Scripts})
SET_BIN_DIR(Assembly Assembly /Mod/Assembly)
SET_PYTHON_PREFIX_SUFFIX(Assembly)
INSTALL(TARGETS Assembly DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@@ -1,123 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development m_solvertem. *
* *
* 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 <math.h>
#include <Standard_Failure.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <gp_Pln.hxx>
#include <GeomAbs_CurveType.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Vertex.hxx>
#include <gp_Pnt.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <TopoDS_Edge.hxx>
#include <gp_Cylinder.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <TopoDS_Face.hxx>
#include <Base/Placement.h>
#include <Base/Console.h>
#include "Constraint.h"
#include "ConstraintPy.h"
#include "Item.h"
#include "Product.h"
using namespace Assembly;
namespace Assembly {
struct ConstraintInitException : std::exception {
const char* what() const throw() {
return "Constraint cout not be initialised: unsoported geometry";
}
};
struct ConstraintPartException : std::exception {
const char* what() const throw() {
return "Constraint cout not be initialised: parts are invalid";
}
};
struct ConstraintLinkException : std::exception {
const char* what() const throw() {
return "Constraint cout not be initialised: unsoported link type";
}
};
PROPERTY_SOURCE(Assembly::Constraint, App::DocumentObject)
const char* Constraint::OrientationEnums[] = {"Parallel","Equal","Opposite","Perpendicular",NULL};
const char* Constraint::TypeEnums[] = {"Fix","Distance","Orientation","Angle","Align","Coincident","None",NULL};
const char* Constraint::SolutionSpaceEnums[] = {"Bidirectional","PositivDirectional","NegativeDirectional",NULL};
Constraint::Constraint()
{
ADD_PROPERTY(First, (0));
ADD_PROPERTY(Second,(0));
ADD_PROPERTY(Value,(0));
ADD_PROPERTY(Orientation, (long(0)));
Orientation.setEnums(OrientationEnums);
ADD_PROPERTY(Type, (long(6)));
Type.setEnums(TypeEnums);
ADD_PROPERTY(SolutionSpace, (long(0)));
SolutionSpace.setEnums(SolutionSpaceEnums);
}
short Constraint::mustExecute() const
{
//if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
return 0;
}
App::DocumentObjectExecReturn* Constraint::execute(void)
{
return App::DocumentObject::StdReturn;
}
PyObject* Constraint::getPyObject(void)
{
if(PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new ConstraintPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
}

View File

@@ -1,74 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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 Assembly_Constraint_H
#define Assembly_Constraint_H
#include <App/PropertyLinks.h>
#include <App/DocumentObject.h>
#include <TopoDS_Shape.hxx>
#include "Solver/Solver.h"
#include "Product.h"
namespace Assembly
{
class AssemblyExport Constraint : public App::DocumentObject
{
PROPERTY_HEADER(Assembly::Constraint);
public:
Constraint();
App::PropertyLinkSub First;
App::PropertyLinkSub Second;
App::PropertyFloat Value;
App::PropertyEnumeration Orientation;
App::PropertyEnumeration SolutionSpace;
App::PropertyEnumeration Type;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderConstraint";
}
PyObject *getPyObject(void);
private:
static const char* OrientationEnums[];
static const char* TypeEnums[];
static const char* SolutionSpaceEnums[];
};
} //namespace Assembly
#endif // Assembly_Constraint_H

View File

@@ -1,76 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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_
#endif
#include <Base/Placement.h>
#include <Base/Console.h>
#include "ConstraintGroupPy.h"
#include "ConstraintGroup.h"
#include "Product.h"
using namespace Assembly;
namespace Assembly {
PROPERTY_SOURCE(Assembly::ConstraintGroup, App::DocumentObject)
ConstraintGroup::ConstraintGroup()
{
ADD_PROPERTY(Constraints,(0));
}
PyObject *ConstraintGroup::getPyObject(void)
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new ConstraintGroupPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
short ConstraintGroup::mustExecute() const
{
//if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
return 0;
}
App::DocumentObjectExecReturn *ConstraintGroup::execute(void)
{
touch();
return App::DocumentObject::StdReturn;
}
}

View File

@@ -1,65 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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 Assembly_ConstraintGroup_H
#define Assembly_ConstraintGroup_H
#include <App/PropertyLinks.h>
#include <App/DocumentObject.h>
#include <App/FeaturePython.h>
#include "Constraint.h"
#include "Solver/Solver.h"
namespace Assembly
{
class AssemblyExport ConstraintGroup : public App::DocumentObject
{
PROPERTY_HEADER(Assembly::ConstraintGroup);
public:
ConstraintGroup();
PyObject *getPyObject(void);
App::PropertyLinkList Constraints;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderConstraintGroup";
}
//@}
};
} //namespace Assembly
#endif // Assembly_ConstraintGroup_H

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="DocumentObjectPy"
Name="ConstraintGroupPy"
Twin="ConstraintGroup"
TwinPointer="ConstraintGroup"
Include="Mod/Assembly/App/ConstraintGroup.h"
Namespace="Assembly"
FatherInclude="App/DocumentObjectPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Base class of all objects in Assembly</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -1,52 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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"
#include "Mod/Assembly/App/ConstraintGroup.h"
#include "Mod/Assembly/App/ConstraintPy.h"
// inclusion of the generated files (generated out of ConstraintGroupPy.xml)
#include "ConstraintGroupPy.h"
#include "ConstraintGroupPy.cpp"
using namespace Assembly;
// returns a string which represents the object e.g. when printed in python
std::string ConstraintGroupPy::representation(void) const
{
return std::string("<ConstraintGroup object>");
}
PyObject *ConstraintGroupPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int ConstraintGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="DocumentObjectPy"
Name="ConstraintPy"
Twin="Constraint"
TwinPointer="Constraint"
Include="Mod/Assembly/App/Constraint.h"
Namespace="Assembly"
FatherInclude="App/DocumentObjectPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Stefan Tröger" EMail="stefantroeger@gmx.net" />
<UserDocu>Base class of all objects in Assembly</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -1,52 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development m_solvertem. *
* *
* 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 "Mod/Assembly/App/Constraint.h"
// inclusion of the generated files (generated out of ItemAssemblyPy.xml)
#include "ConstraintPy.h"
#include "ConstraintPy.cpp"
using namespace Assembly;
// returns a string which represents the object e.g. when printed in python
std::string ConstraintPy::representation(void) const
{
return std::string("<Assembly constraint object>");
}
PyObject *ConstraintPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int ConstraintPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -1,74 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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_
#endif
#include <Base/Placement.h>
#include <Base/Uuid.h>
#include <Base/Console.h>
#include "Item.h"
#include "ItemPy.h"
#include <Standard_Failure.hxx>
using namespace Assembly;
namespace Assembly {
PROPERTY_SOURCE_ABSTRACT(Assembly::Item, App::GeoFeature)
Item::Item()
{
ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information");
}
short Item::mustExecute() const
{
//if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
return 0;
}
App::DocumentObjectExecReturn *Item::execute(void)
{
Base::Console().Message("Recalculate Assembly::Item\n");
return App::DocumentObject::StdReturn;
}
PyObject *Item::getPyObject(void)
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new ItemPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
}

View File

@@ -1,65 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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 Assembly_Item_H
#define Assembly_Item_H
#include <App/PropertyStandard.h>
#include <App/GeoFeature.h>
#include <TopoDS_Shape.hxx>
namespace Assembly
{
/// Base class of all Assembly objects
class AssemblyExport Item : public App::GeoFeature
{
PROPERTY_HEADER(Assembly::Item);
public:
Item();
~Item() {};
/// Meta descriptions
App::PropertyMap Meta;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderItem";
}
//@}
PyObject *getPyObject(void);
};
} //namespace Assembly
#endif // ASSEMBLY_Item_H

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="DocumentObjectPy"
Name="ItemPy"
Twin="Item"
TwinPointer="Item"
Include="Mod/Assembly/App/Item.h"
Namespace="Assembly"
FatherInclude="App/DocumentObjectPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Base class of all objects in Assembly</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -1,57 +0,0 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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"
#include "Mod/Assembly/App/Item.h"
// inclusion of the generated files (generated out of ItemPy.xml)
#include "ItemPy.h"
#include "ItemPy.cpp"
using namespace Assembly;
// returns a string which represents the object e.g. when printed in python
std::string ItemPy::representation(void) const
{
return std::string("<Item object>");
}
PyObject *ItemPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int ItemPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -1,233 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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_
#endif
#include <Base/Placement.h>
#include <Base/Console.h>
#include "PartRef.h"
#include "Product.h"
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/BodyBase.h>
#include <PartRefPy.h>
#include <TopoDS.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <BRep_Tool.hxx>
#include <GeomAbs_CurveType.hxx>
using namespace Assembly;
namespace Assembly {
struct AssemblyItemException : std::exception {
const char* what() const throw() { return "Assembly items are in wrong structure";}
};
PROPERTY_SOURCE(Assembly::PartRef, App::GeoFeature)
PartRef::PartRef() {
ADD_PROPERTY(Model, (0));
ADD_PROPERTY(Annotation,(0));
}
short PartRef::mustExecute() const {
//if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
return 0;
}
App::DocumentObjectExecReturn* PartRef::execute(void) {
this->touch();
return App::DocumentObject::StdReturn;
}
TopoDS_Shape PartRef::getShape(void) const {
App::DocumentObject* obj = Model.getValue();
if(obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
return static_cast<Part::Feature*>(obj)->Shape.getValue();
}
return TopoDS_Shape();
}
PyObject* PartRef::getPyObject(void) {
if(PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new PartRefPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
bool PartRef::holdsObject(App::DocumentObject* obj) const {
//get the body object and the relevant model list
Part::BodyBase* base = static_cast<Part::BodyBase*>(Model.getValue());
const std::vector<App::DocumentObject*>& vector = base->Model.getValues();
//check if it holds the relevant document object
return std::find(vector.begin(), vector.end(), obj)!=vector.end();
}
void PartRef::setCalculatedPlacement(std::shared_ptr< Part3D > part) {
//part is the same as m_part, so it doesn't matter which one we use
Base::Placement p = dcm::get<Base::Placement>(part);
Product* ass = getParentAssembly();
if(!ass)
throw AssemblyItemException();
if(ass->Rigid.getValue())
Placement.setValue(p);
else
Placement.setValue(ass->m_downstream_placement.inverse()*p);
}
Product* PartRef::getParentAssembly() {
typedef std::vector<App::DocumentObject*>::const_iterator iter;
const std::vector<App::DocumentObject*>& vector = getInList();
for(iter it=vector.begin(); it != vector.end(); it++) {
if((*it)->getTypeId() == Assembly::Product::getClassTypeId())
return static_cast<Assembly::Product*>(*it);
};
return (Product*)NULL;
}
void PartRef::ensureInitialisation() {
Product* ass = getParentAssembly();
if(!ass)
throw AssemblyItemException();
std::shared_ptr<Solver> solver = ass->m_solver;
if(!solver)
throw AssemblyItemException();
if(!solver->hasPart(Uid.getValueStr())) {
//if the assembly is not rigid it was not added to the solver, so we need to incorporate its placement
if(ass->Rigid.getValue()) {
m_part = solver->createPart(Placement.getValue(), Uid.getValueStr());
}
else {
m_part = solver->createPart(ass->m_downstream_placement*Placement.getValue(), Uid.getValueStr());
}
m_part->connectSignal<dcm::recalculated>(boost::bind(&PartRef::setCalculatedPlacement, this, _1));
};
}
std::shared_ptr< Geometry3D > PartRef::getGeometry3D(const char* Type) {
//check if the item is initialized
if(!m_part)
return std::shared_ptr< Geometry3D >();
std::shared_ptr<Geometry3D> geometry;
if(m_part->hasGeometry3D(Type)) {
return m_part->getGeometry3D(Type);
}
else {
Part::TopoShape ts;
App::DocumentObject* obj = Model.getValue();
if(obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts = static_cast<Part::Feature*>(obj)->Shape.getShape();
}
else
return std::shared_ptr< Geometry3D >();
TopoDS_Shape s = ts.getSubShape(Type);
if(s.ShapeType() == TopAbs_FACE) {
TopoDS_Face face = TopoDS::Face(s);
BRepAdaptor_Surface surface(face);
switch(surface.GetType()) {
case GeomAbs_Plane: {
gp_Pln plane = surface.Plane();
if(face.Orientation()==TopAbs_REVERSED) {
gp_Dir dir = plane.Axis().Direction();
plane = gp_Pln(plane.Location(), dir.Reversed());
}
geometry = m_part->addGeometry3D(plane, Type, dcm::Local);
break;
}
case GeomAbs_Cylinder: {
gp_Cylinder cyl = surface.Cylinder();
geometry = m_part->addGeometry3D(cyl, Type, dcm::Local);
break;
}
default:
Base::Console().Message("Unsupported Surface Geometry Type at selection\n");
return std::shared_ptr< Geometry3D >();
}
}
else
if(s.ShapeType() == TopAbs_EDGE) {
TopoDS_Edge edge = TopoDS::Edge(s);
BRepAdaptor_Curve curve(edge);
switch(curve.GetType()) {
case GeomAbs_Line: {
gp_Lin line = curve.Line();
geometry = m_part->addGeometry3D(line, Type, dcm::Local);
break;
}
default:
Base::Console().Message("Unsupported Curve Geometry Type at selection \n");
return std::shared_ptr< Geometry3D >();
}
}
else
if(s.ShapeType() == TopAbs_VERTEX) {
TopoDS_Vertex v1 = TopoDS::Vertex(s);
gp_Pnt point = BRep_Tool::Pnt(v1);
geometry = m_part->addGeometry3D(point, Type, dcm::Local);
}
else {
Base::Console().Message("Unsupported Topology Type at selection\n");
return std::shared_ptr< Geometry3D >();
}
};
return geometry;
}
}

View File

@@ -1,74 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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 Assembly_ItemPart_H
#define Assembly_ItemPart_H
#include <App/PropertyLinks.h>
#include <App/GeoFeature.h>
#include "Solver/Solver.h"
namespace Assembly
{
class Product;
class AssemblyExport PartRef : public App::GeoFeature
{
PROPERTY_HEADER(Assembly::PartRef);
public:
PartRef();
App::PropertyLink Item;
//App::PropertyLinkList Annotation;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderItemPart";
}
PyObject *getPyObject(void);
//@}
//virtual TopoDS_Shape getShape(void) const;
bool holdsObject(App::DocumentObject* obj) const;
Product* getParentAssembly();
void ensureInitialisation();
std::shared_ptr<Part3D> m_part;
virtual std::shared_ptr<Geometry3D> getGeometry3D(const char* Type );
void setCalculatedPlacement( std::shared_ptr<Part3D> part );
};
} //namespace Assembly
#endif // Assembly_ItemPart_H

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="ItemPy"
Name="PartRefPy"
Twin="PartRef"
TwinPointer="PartRef"
Include="Mod/Assembly/App/PartRef.h"
Namespace="Assembly"
FatherInclude="Mod/Assembly/App/ItemPy.h"
FatherNamespace="Assembly">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Base class of all objects in Assembly</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -1,56 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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"
#include "Mod/Assembly/App/PartRef.h"
// inclusion of the generated files (generated out of PartRefPy.xml)
#include "PartRefPy.h"
#include "PartRefPy.cpp"
using namespace Assembly;
// returns a string which represents the object e.g. when printed in python
std::string PartRefPy::representation(void) const
{
return std::string("<PartRef object>");
}
PyObject *PartRefPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int PartRefPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -1,24 +0,0 @@
/***************************************************************************
* 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"

View File

@@ -1,242 +0,0 @@
/***************************************************************************
* 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 ASSEMBLY_PRECOMPILED_H
#define ASSEMBLY_PRECOMPILED_H
#include <FCConfig.h>
// Exporting of App classes
#ifdef FC_OS_WIN32
# define AssemblyExport __declspec(dllexport)
# define PartExport __declspec(dllimport)
# define MeshExport __declspec(dllimport)
#else // for Linux
# define AssemblyExport
# define PartExport
# define MeshExport
#endif
#ifdef _PreComp_
// standard
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <bitset>
// OpenCasCade =====================================================================================
// Base
#include <Standard_Failure.hxx>
#include <Standard_GUID.hxx>
#include <Standard_AbortiveTransaction.hxx>
#include <Standard_Address.hxx>
#include <Standard_AncestorIterator.hxx>
//#include <Standard_BasicMap.hxx>
//#include <Standard_BasicMapIterator.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Byte.hxx>
#include <Standard_Character.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_CString.hxx>
#include <Standard_ctype.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_DimensionMismatch.hxx>
#include <Standard_DivideByZero.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_ExtCharacter.hxx>
#include <Standard_ExtString.hxx>
#include <Standard_Failure.hxx>
//#include <Standard_ForMapOfTypes.hxx>
#include <Standard_GUID.hxx>
#include <Standard_ImmutableObject.hxx>
#include <Standard_Integer.hxx>
#include <Standard_InternalType.hxx>
#include <Standard_IStream.hxx>
#include <Standard_KindOfType.hxx>
#include <Standard_LicenseError.hxx>
#include <Standard_LicenseNotFound.hxx>
#include <Standard_Macro.hxx>
//#include <Standard_MapOfTypes.hxx>
#include <Standard_math.hxx>
#include <Standard_MultiplyDefined.hxx>
//#include <Standard_MyMapOfStringsHasher.hxx>
//#include <Standard_MyMapOfTypes.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_NoMoreObject.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_NullObject.hxx>
#include <Standard_NullValue.hxx>
#include <Standard_NumericError.hxx>
#include <Standard_OId.hxx>
#include <Standard_OStream.hxx>
#include <Standard_OutOfMemory.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_Overflow.hxx>
#include <Standard_Persistent.hxx>
#include <Standard_Persistent_proto.hxx>
//#include <Standard_PForMapOfTypes.hxx>
#include <Standard_PrimitiveTypes.hxx>
#include <Standard_ProgramError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_Real.hxx>
#include <Standard_ShortReal.hxx>
#include <Standard_SStream.hxx>
#include <Standard_Static.hxx>
#include <Standard_Storable.hxx>
#include <Standard_Stream.hxx>
//#include <Standard_theForMapOfTypes.hxx>
#include <Standard_TooManyUsers.hxx>
#include <Standard_Transient.hxx>
#include <Standard_Transient_proto.hxx>
#include <Standard_Type.hxx>
#include <Standard_TypeDef.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_Underflow.hxx>
#include <Standard_UUID.hxx>
#include <Standard_WayOfLife.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_SequenceOfExtendedString.hxx>
#include <BRep_Builder.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepBuilderAPI.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepTools.hxx>
#include <BRepTools_ShapeSet.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Result.hxx>
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
#include <BRepTools.hxx>
#include <Standard_DefineHandle.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <Geom_Axis2Placement.hxx>
#include <Geom_CartesianPoint.hxx>
#include <Geom_Line.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_Circle.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_Parabola.hxx>
#include <Geom_Plane.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <GeomTools_Curve2dSet.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Circ.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Cone.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Elips.hxx>
#include <gp_Hypr.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Lin.hxx>
#include <gp_Parab.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Sphere.hxx>
#include <gp_Torus.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <MMgt_TShared.hxx>
#include <Precision.hxx>
#include <Quantity_Factor.hxx>
#include <Quantity_Length.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Quantity_PhysicalQuantity.hxx>
#include <Quantity_PlaneAngle.hxx>
#include <Quantity_TypeOfColor.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_CString.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Integer.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Macro.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Real.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TColStd_MapIteratorOfMapOfTransient.hxx>
#include <TColStd_MapOfTransient.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_ListIteratorOfListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <UnitsAPI.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
// --- ODE ----------
#include <ode/ode.h>
#endif // _PreComp_
#endif

View File

@@ -1,89 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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 <BRep_Builder.hxx>
# include <TopoDS_Compound.hxx>
#include <boost/exception/get_error_info.hpp>
#endif
#include <Base/Placement.h>
#include <Base/Console.h>
#include <Base/Exception.h>
#include "Product.h"
#include "ConstraintGroup.h"
using namespace Assembly;
namespace Assembly {
PROPERTY_SOURCE(Assembly::Product, Assembly::Item)
Product::Product() {
ADD_PROPERTY(Items,(0));
ADD_PROPERTY_TYPE(Material,(),0,App::Prop_None,"Map with material properties");
// create the uuid for the document
Base::Uuid id;
ADD_PROPERTY_TYPE(Id,(""),0,App::Prop_None,"ID (Part-Number) of the Item");
ADD_PROPERTY_TYPE(Uid,(id),0,App::Prop_None,"UUID of the Item");
// license stuff
ADD_PROPERTY_TYPE(License,("CC BY 3.0"),0,App::Prop_None,"License string of the Item");
ADD_PROPERTY_TYPE(LicenseURL,("http://creativecommons.org/licenses/by/3.0/"),0,App::Prop_None,"URL to the license text/contract");
// color and appearance
ADD_PROPERTY(Color,(1.0,1.0,1.0,1.0)); // set transparent -> not used
ADD_PROPERTY(Visibility,(true));
}
short Product::mustExecute() const {
return 0;
}
App::DocumentObjectExecReturn* Product::execute(void) {
Base::Console().Message("Execute\n");
return App::DocumentObject::StdReturn;
}
//PyObject* Product::getPyObject(void) {
// if(PythonObject.is(Py::_None())) {
// // ref counter is set to 1
// PythonObject = Py::Object(new ProductPy(this),true);
// }
//
// return Py::new_reference_to(PythonObject);
//}
} //assembly

View File

@@ -1,96 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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 ItemAssembly_ItemAssembly_H
#define ItemAssembly_ItemAssembly_H
#include <App/PropertyStandard.h>
#include "Item.h"
#include "Solver/Solver.h"
namespace Assembly
{
class AssemblyExport Product : public Assembly::Item
{
PROPERTY_HEADER(Assembly::Product);
public:
Product();
/// Items of the Product
App::PropertyLinkList Items;
/** @name base properties of all Assembly Items
* This properties correspond mostly to the meta information
* in the App::Document class
*/
//@{
/// Id e.g. Part number
App::PropertyString Id;
/// unique identifier of the Item
App::PropertyUUID Uid;
/// material descriptions
App::PropertyMap Material;
/** License string
* Holds the short license string for the Item, e.g. CC-BY
* for the Creative Commons license suit.
*/
App::PropertyString License;
/// License description/contract URL
App::PropertyString LicenseURL;
//@}
/** @name Visual properties */
//@{
/** Base color of the Item
If the transparency value is 1.0
the color or the next hierarchy is used
*/
App::PropertyColor Color;
/// Visibility
App::PropertyBool Visibility;
//@}
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderProduct";
}
//PyObject *getPyObject(void);
//@}
};
} //namespace Assembly
#endif // Assembly_ItemAssembly_H

View File

@@ -1,72 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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 <BRep_Builder.hxx>
# include <TopoDS_Compound.hxx>
#include <boost/exception/get_error_info.hpp>
#endif
#include <Base/Placement.h>
#include <Base/Console.h>
#include <App/Part.h>
#include "ProductRef.h"
#include "ConstraintGroup.h"
#include "ProductRefPy.h"
using namespace Assembly;
namespace Assembly {
PROPERTY_SOURCE(Assembly::ProductRef, Assembly::Item)
ProductRef::ProductRef() {
ADD_PROPERTY(Item,(0));
}
short ProductRef::mustExecute() const {
return 0;
}
App::DocumentObjectExecReturn* ProductRef::execute(void)
{
return App::DocumentObject::StdReturn;
}
PyObject* ProductRef::getPyObject(void) {
if(PythonObject.is(Py::_None())) {
// ref counter is set to 1
PythonObject = Py::Object(new ProductRefPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
} //assembly

View File

@@ -1,64 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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 ProductRef_ProductRef_H
#define ProductRef_ProductRef_H
#include <App/PropertyStandard.h>
#include "Item.h"
#include "Solver/Solver.h"
namespace Assembly
{
class AssemblyExport ProductRef : public Assembly::Item
{
PROPERTY_HEADER(Assembly::ProductRef);
public:
ProductRef();
/// The one and only GeomtricObject referenced
App::PropertyLink Item;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "AssemblyGui::ViewProviderProductRef";
}
PyObject *getPyObject(void);
//@}
};
} //namespace Assembly
#endif // Assembly_ProductRef_H

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="ItemPy"
Name="ProductRefPy"
Twin="ProductRef"
TwinPointer="ProductRef"
Include="Mod/Assembly/App/ProductRef.h"
Namespace="Assembly"
FatherInclude="Mod/Assembly/App/ItemPy.h"
FatherNamespace="Assembly">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>Base class of all objects in Assembly</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -1,49 +0,0 @@
/***************************************************************************
* Copyright (c) 2012 Juergen 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"
#include "Mod/Assembly/App/ProductRef.h"
// inclusion of the generated files (generated out of ProductRefPy.xml)
#include "ProductRefPy.h"
#include "ProductRefPy.cpp"
using namespace Assembly;
// returns a string which represents the object e.g. when printed in python
std::string ProductRefPy::representation(void) const
{
return std::string("<ProductRef object>");
}
PyObject *ProductRefPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int ProductRefPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -1,412 +0,0 @@
/***************************************************************************
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.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 SOLVER_H
#define SOLVER_H
#include "opendcm/core.hpp"
#ifdef ASSEMBLY_DEBUG_FACILITIES
#include "opendcm/modulestate.hpp"
#endif
#include "opendcm/module3d.hpp"
#include "opendcm/modulepart.hpp"
#include <Base/Placement.h>
#include <Base/Console.h>
#include <gp_Pnt.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <gp_Cylinder.hxx>
struct gp_pnt_accessor {
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
switch(ID) {
case 0:
return t.X();
case 1:
return t.Y();
case 2:
return t.Z();
default:
return 0;
};
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
switch(ID) {
case 0:
t.SetX(value);
break;
case 1:
t.SetY(value);
break;
case 2:
t.SetZ(value);
break;
};
};
template<typename T>
void finalize(T& t) {};
};
struct gp_lin_accessor {
gp_Pnt pnt;
double dx,dy,dz;
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
switch(ID) {
case 0:
return t.Location().X();
case 1:
return t.Location().Y();
case 2:
return t.Location().Z();
case 3:
return t.Direction().X();
case 4:
return t.Direction().Y();
case 5:
return t.Direction().Z();
default:
return 0;
};
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
switch(ID) {
case 0:
pnt.SetX(value);
break;
case 1:
pnt.SetY(value);
break;
case 2:
pnt.SetZ(value);
break;
case 3:
dx=(value);
break;
case 4:
dy=(value);
break;
case 5:
dz=(value);
break;
};
};
template<typename T>
void finalize(T& t) {
t.SetLocation(pnt);
t.SetDirection(gp_Dir(dx,dy,dz));
};
};
struct gp_pln_accessor {
gp_Pnt pnt;
double dx,dy,dz;
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
switch(ID) {
case 0:
return t.Axis().Location().X();
case 1:
return t.Axis().Location().Y();
case 2:
return t.Axis().Location().Z();
case 3:
return t.Axis().Direction().X();
case 4:
return t.Axis().Direction().Y();
case 5:
return t.Axis().Direction().Z();
default:
return 0;
};
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
switch(ID) {
case 0:
pnt.SetX(value);
break;
case 1:
pnt.SetY(value);
break;
case 2:
pnt.SetZ(value);
break;
case 3:
dx=value;
break;
case 4:
dy=value;
break;
case 5:
dz=value;
break;
};
};
template<typename T>
void finalize(T& t) {
t.SetAxis(gp_Ax1(pnt,gp_Dir(dx,dy,dz)));
};
};
struct gp_cylinder_accessor {
gp_Pnt pnt;
double dx,dy,dz;
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
switch(ID) {
case 0:
return t.Axis().Location().X();
case 1:
return t.Axis().Location().Y();
case 2:
return t.Axis().Location().Z();
case 3:
return t.Axis().Direction().X();
case 4:
return t.Axis().Direction().Y();
case 5:
return t.Axis().Direction().Z();
case 6:
return t.Radius();
default:
return 0;
};
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
switch(ID) {
case 0:
pnt.SetX(value);
break;
case 1:
pnt.SetY(value);
break;
case 2:
pnt.SetZ(value);
break;
case 3:
dx=value;
break;
case 4:
dy=value;
break;
case 5:
dz=value;
break;
case 6:
t.SetRadius(value);
break;
};
};
template<typename T>
void finalize(T& t) {
t.SetAxis(gp_Ax1(pnt,gp_Dir(dx,dy,dz)));
};
};
struct placement_accessor {
double q0, q1, q2, q3;
Base::Vector3d vec;
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
t.getRotation().getValue(q0,q1,q2,q3);
switch(ID) {
case 0:
return q3;
case 1:
return q0;
case 2:
return q1;
case 3:
return q2;
case 4:
return t.getPosition()[0];
case 5:
return t.getPosition()[1];
case 6:
return t.getPosition()[2];
default:
return 0;
};
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
switch(ID) {
case 0:
q3 = value;
break;
case 1:
q0 = value;
break;
case 2:
q1 = value;
break;
case 3:
q2 = value;
break;
case 4:
vec[0] = value;
break;
case 5:
vec[1] = value;
break;
case 6:
vec[2] = value;
break;
};
};
template<typename T>
void finalize(T& t) {
//need to do it at once as setting every value step by step would always normalize the rotation and
//therefore give a false value
Base::Rotation rot(q0,q1,q2,q3);
t.setRotation(rot);
t.setPosition(vec);
};
};
//geometry_traits for opencascade
namespace dcm {
template<>
struct geometry_traits<gp_Pnt> {
typedef tag::point3D tag;
typedef modell::XYZ modell;
typedef gp_pnt_accessor accessor;
};
template<>
struct geometry_traits<gp_Lin> {
typedef tag::line3D tag;
typedef modell::XYZ2 modell;
typedef gp_lin_accessor accessor;
};
template<>
struct geometry_traits<gp_Pln> {
typedef tag::plane3D tag;
typedef modell::XYZ2 modell;
typedef gp_pln_accessor accessor;
};
template<>
struct geometry_traits<gp_Cylinder> {
typedef tag::cylinder3D tag;
typedef modell::XYZ2P modell;
typedef gp_cylinder_accessor accessor;
};
template<>
struct geometry_traits<Base::Placement> {
typedef tag::part tag;
typedef modell::quaternion_wxyz_vec3 modell;
typedef placement_accessor accessor;
};
}
//our constraint solving system
typedef dcm::Kernel<double> Kernel;
typedef dcm::Module3D< mpl::vector4< gp_Pnt, gp_Lin, gp_Pln, gp_Cylinder>, std::string > Module3D;
typedef dcm::ModulePart< mpl::vector1< Base::Placement >, std::string > ModulePart;
#ifdef ASSEMBLY_DEBUG_FACILITIES
typedef dcm::System<Kernel, Module3D, ModulePart, dcm::ModuleState> Solver;
#else
typedef dcm::System<Kernel, Module3D, ModulePart> Solver;
#endif
typedef ModulePart::type<Solver>::Part Part3D;
typedef Module3D::type<Solver>::Geometry3D Geometry3D;
typedef Module3D::type<Solver>::Constraint3D Constraint3D;
#endif //SOLVER_H

View File

@@ -1,30 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Solver.h"
#ifdef DCM_EXTERNAL_CORE
#include DCM_EXTERNAL_CORE_INCLUDE_01
DCM_EXTERNAL_CORE_01( Solver )
#endif
#ifdef DCM_EXTERNAL_3D
#include DCM_EXTERNAL_3D_INCLUDE_01
DCM_EXTERNAL_3D_01( Solver )
#endif

View File

@@ -1,25 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Solver.h"
#ifdef DCM_EXTERNAL_3D
#include DCM_EXTERNAL_3D_INCLUDE_02
DCM_EXTERNAL_3D_02(Solver)
#endif

View File

@@ -1,25 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Solver.h"
#ifdef DCM_EXTERNAL_3D
#include DCM_EXTERNAL_3D_INCLUDE_03
DCM_EXTERNAL_3D_03(Solver)
#endif

View File

@@ -1,44 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Solver.h"
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_001
DCM_EXTERNAL_STATE_001( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_002
DCM_EXTERNAL_STATE_002( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_003
DCM_EXTERNAL_STATE_003( Solver )
#include DCM_EXTERNAL_STATE_INCLUDE_009
DCM_EXTERNAL_STATE_009( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_004
DCM_EXTERNAL_STATE_004( Solver )
#endif

View File

@@ -1,40 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Solver.h"
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_005
DCM_EXTERNAL_STATE_005( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_006
DCM_EXTERNAL_STATE_006( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_007
DCM_EXTERNAL_STATE_007( Solver )
#endif
#ifdef DCM_EXTERNAL_STATE
#include DCM_EXTERNAL_STATE_INCLUDE_008
DCM_EXTERNAL_STATE_008( Solver )
#endif

View File

@@ -1,3 +0,0 @@
/usr/include/eigen3
/home/stefan/Projects/openDCM/opendcm/
/home/stefan/Projects/openDCM/

View File

@@ -1,59 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CORE_H
#define DCM_CORE_H
#ifdef _WIN32
//warning about excessively long decorated names, won't affect the code correctness
#pragma warning( disable : 4503 )
//warning about changed pod initialising behaviour (boost blank in variant)
#pragma warning( disable : 4345 )
//warning about multiple assignment operators in Equation
#pragma warning( disable : 4522 )
//disable boost concept checks, as some of them have alignment problems which bring msvc to an error
//(for example DFSvisitor check in boost::graph::depht_first_search)
//this has no runtime effect as these are only compile time checks
#include <boost/concept/assert.hpp>
#undef BOOST_CONCEPT_ASSERT
#define BOOST_CONCEPT_ASSERT(Model)
#include <boost/concept_check.hpp>
#endif
#include "core/defines.hpp"
#include "core/geometry.hpp"
#include "core/kernel.hpp"
#include "core/system.hpp"
#ifdef DCM_EXTERNAL_CORE
#define DCM_EXTERNAL_CORE_INCLUDE_01 "opendcm/core/imp/system_imp.hpp"
#define DCM_EXTERNAL_CORE_01( Sys )\
template class dcm::System<Sys::Kernel, Sys::Module1, Sys::Module2, Sys::Module3>; \
template struct dcm::Equation<dcm::Distance, mpl::vector2<double, dcm::SolutionSpace>, 1>; \
template struct dcm::Equation<dcm::Orientation, dcm::Direction, 2, dcm::rotation>; \
template struct dcm::Equation<dcm::Angle, mpl::vector2<double, dcm::SolutionSpace>, 3, dcm::rotation>;
#endif //external
#endif //DCM_CORE_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,326 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_CONSTRAINT_H
#define GCM_CONSTRAINT_H
#include<Eigen/StdVector>
#include <assert.h>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/any.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/preprocessor.hpp>
#include "traits.hpp"
#include "object.hpp"
#include "equations.hpp"
#include "geometry.hpp"
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
namespace detail {
//metafunction to avoid ot-of-range access of mpl sequences
template<typename Sequence, int Value>
struct in_range_value {
typedef typename mpl::prior<mpl::size<Sequence> >::type last_id;
typedef typename mpl::min< mpl::int_<Value>, last_id>::type type;
};
//type erasure container for constraints
template<typename Sys, int Dim>
class Constraint {
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::DynStride DS;
typedef typename Kernel::MappedEquationSystem MES;
typedef std::shared_ptr<details::Geometry<Kernel, Dim, typename Sys::geometries> > geom_ptr;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
//metafunction to create equation from consraint and tags
template<typename C, typename T1, typename T2>
struct equation {
typedef typename C::template type<Kernel, T1, T2> type;
};
public:
Constraint(geom_ptr f, geom_ptr s);
~Constraint();
//workaround until better analysing class is created
// TODO: remove diasable once analyser is available
void disable() {
content->disable();
};
std::vector<boost::any> getGenericEquations();
std::vector<boost::any> getGenericConstraints();
std::vector<const std::type_info*> getEquationTypes();
std::vector<const std::type_info*> getConstraintTypes();
template<typename Tag1, typename Tag2, typename ConstraintVector>
void initializeFromTags(ConstraintVector& obj);
template<typename ConstraintVector>
void initialize(ConstraintVector& obj);
protected:
//initialising from geometry functions
template<typename WhichType, typename ConstraintVector>
void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::false_);
template<typename WhichType, typename ConstraintVector>
void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::true_);
template<typename WhichType, typename FirstType, typename ConstraintVector>
void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::false_);
template<typename WhichType, typename FirstType, typename ConstraintVector>
void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::true_);
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::false_);
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::true_);
int equationCount();
void calculate(Scalar scale, AccessType access = general);
void treatLGZ();
void setMaps(MES& mes);
void collectPseudoPoints(Vec& vec1, Vec& vec2);
//Equation is the constraint with types, the EquationSet hold all needed Maps for calculation
template<typename Equation>
struct EquationSet {
EquationSet() : m_diff_first(NULL,0,DS(0,0)), m_diff_first_rot(NULL,0,DS(0,0)),
m_diff_second(NULL,0,DS(0,0)), m_diff_second_rot(NULL,0,DS(0,0)),
m_residual(NULL,0,DS(0,0)), enabled(true) {};
Equation m_eq;
typename Kernel::VectorMap m_diff_first, m_diff_first_rot; //first geometry diff
typename Kernel::VectorMap m_diff_second, m_diff_second_rot; //second geometry diff
typename Kernel::VectorMap m_residual;
bool enabled;
AccessType access;
typedef Equation eq_type;
};
struct placeholder {
virtual ~placeholder() {}
virtual placeholder* resetConstraint(geom_ptr first, geom_ptr second) const = 0;
virtual void calculate(geom_ptr first, geom_ptr second, Scalar scale, AccessType access = general) = 0;
virtual void treatLGZ(geom_ptr first, geom_ptr second) = 0;
virtual int equationCount() = 0;
virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second) = 0;
virtual void collectPseudoPoints(geom_ptr first, geom_ptr second, Vec& vec1, Vec& vec2) = 0;
virtual void disable() = 0;
virtual placeholder* clone() = 0;
//some runtime type infos are needed, as we can't access the contents with arbitrary functors
virtual std::vector<boost::any> getGenericEquations() = 0;
virtual std::vector<boost::any> getGenericConstraints() = 0;
virtual std::vector<const std::type_info*> getEquationTypes() = 0;
virtual std::vector<const std::type_info*> getConstraintTypes() = 0;
};
int value;
public:
template< typename ConstraintVector, typename tag1, typename tag2>
struct holder : public placeholder {
//transform the constraints into eqautions with the now known types
typedef typename mpl::fold< ConstraintVector, mpl::vector<>,
mpl::push_back<mpl::_1, equation<mpl::_2, tag1, tag2> > >::type EquationVector;
//create a vector of EquationSets with some mpl trickery
typedef typename mpl::fold< EquationVector, mpl::vector<>,
mpl::push_back<mpl::_1, EquationSet<mpl::_2> > >::type eq_set_vector;
typedef typename fusion::result_of::as_vector<eq_set_vector>::type EquationSets;
typedef ConstraintVector Objects;
template<typename T>
struct has_option {
//we get the index of the eqaution in the eqaution vector, and as it is the same
//as the index of the constraint in the constraint vector we can extract the
//option type and check if it is no_option
typedef typename mpl::find<EquationVector, T>::type iterator;
typedef typename mpl::distance<typename mpl::begin<EquationVector>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<EquationVector>::type > >));
typedef typename fusion::result_of::at<ConstraintVector, distance>::type option_type;
typedef mpl::not_<boost::is_same<option_type, no_option> > type;
};
struct OptionSetter {
Objects& objects;
OptionSetter(Objects& val);
//only set the value if the equation has a option
template< typename T >
typename boost::enable_if<typename has_option<T>::type, void>::type
operator()(EquationSet<T>& val) const;
//if the equation has no option we do nothing!
template< typename T >
typename boost::enable_if<mpl::not_<typename has_option<T>::type>, void>::type
operator()(EquationSet<T>& val) const;
};
struct Calculator {
geom_ptr first, second;
Scalar scale;
AccessType access;
Calculator(geom_ptr f, geom_ptr s, Scalar sc, AccessType a = general);
template< typename T >
void operator()(T& val) const;
};
struct MapSetter {
MES& mes;
geom_ptr first, second;
MapSetter(MES& m, geom_ptr f, geom_ptr s);
template< typename T >
void operator()(T& val) const;
};
struct PseudoCollector {
Vec& points1;
Vec& points2;
geom_ptr first,second;
PseudoCollector(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2);
template< typename T >
void operator()(T& val) const;
};
struct LGZ {
geom_ptr first,second;
LGZ(geom_ptr f, geom_ptr s);
template< typename T >
void operator()(T& val) const;
};
struct EquationCounter {
int& count;
EquationCounter(int& c) : count(c) {};
template< typename T >
void operator()(T& val) const {
if(val.enabled)
count++;
};
};
//workaround until we have a better analyser class
struct disabler {
template<typename T>
void operator()(T& val) const {
val.enabled = false;
};
};
struct GenericEquations {
std::vector<boost::any>& vec;
GenericEquations(std::vector<boost::any>& v);
template<typename T>
void operator()(T& val) const;
};
struct GenericConstraints {
std::vector<boost::any>& vec;
GenericConstraints(std::vector<boost::any>& v);
template<typename T>
void operator()(T& val) const;
};
struct Types {
std::vector<const std::type_info*>& vec;
Types(std::vector<const std::type_info*>& v);
template<typename T>
void operator()(T& val) const;
};
holder(Objects& obj);
virtual void calculate(geom_ptr first, geom_ptr second, Scalar scale, AccessType a = general);
virtual void treatLGZ(geom_ptr first, geom_ptr second);
virtual placeholder* resetConstraint(geom_ptr first, geom_ptr second) const;
virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second);
virtual void collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2);
virtual placeholder* clone();
virtual int equationCount();
virtual void disable();
virtual std::vector<boost::any> getGenericEquations();
virtual std::vector<boost::any> getGenericConstraints();
virtual std::vector<const std::type_info*> getEquationTypes();
virtual std::vector<const std::type_info*> getConstraintTypes();
EquationSets m_sets;
Objects m_objects;
protected:
void for_each(EquationSets m_sets, Calculator Calculator);
};
placeholder* content;
Connection cf, cs;
public:
geom_ptr first, second;
};
};//detail
};//dcm
#ifndef DCM_EXTERNAL_CORE
#include "imp/constraint_imp.hpp"
#include "imp/constraint_holder_imp.hpp"
#endif
#endif //GCM_CONSTRAINT_H

View File

@@ -1,41 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DEFINES_CORE_H
#define GCM_DEFINES_CORE_H
#include <boost/exception/exception.hpp>
#include <string>
namespace dcm {
//all solving related errors
typedef boost::error_info<struct user_message,std::string> error_message;
typedef boost::error_info<struct first_geom, std::string> error_type_first_geometry;
typedef boost::error_info<struct second_geom, std::string> error_type_second_geometry;
//exception codes are needed by the user
struct creation_error : virtual boost::exception {};
struct solving_error : virtual boost::exception {};
struct constraint_error : virtual boost::exception {};
} //dcm
#endif //GCM_DEFINES_CORE_H

View File

@@ -1,422 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EQUATIONS_H
#define DCM_EQUATIONS_H
#include <assert.h>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/not.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/as_map.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/filter_view.hpp>
#include <boost/exception/exception.hpp>
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
#include "kernel.hpp"
namespace dcm {
//the possible directions
enum Direction { parallel, equal, opposite, perpendicular };
//the possible solution spaces
enum SolutionSpace {bidirectional, positiv_directional, negative_directional};
struct no_option {};
template<typename Kernel>
struct Pseudo {
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
template <typename DerivedA,typename DerivedB>
void calculatePseudo(const E::MatrixBase<DerivedA>& param1, Vec& v1, const E::MatrixBase<DerivedB>& param2, Vec& v2) {};
};
template<typename Kernel>
struct Scale {
void setScale(typename Kernel::number_type scale) {};
};
template<typename Kernel>
struct PseudoScale {
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
template <typename DerivedA,typename DerivedB>
void calculatePseudo(const E::MatrixBase<DerivedA>& param1, Vec& v1, const E::MatrixBase<DerivedB>& param2, Vec& v2) {};
void setScale(typename Kernel::number_type scale) {};
};
//type to allow a metaprogramming check for a Equation
struct EQ {};
//template<typename Seq, typename T>
//struct pushed_seq;
//metafunctions to retrieve the options of an equation
template<typename T>
struct options {
typedef typename T::options type;
};
template<>
struct options< mpl::arg<-1> > {
typedef fusion::map<> type;
};
template<typename Eq, typename Opt>
struct has_option : public mpl::if_<mpl::has_key<typename options<Eq>::type, Opt>, boost::true_type, boost::false_type>::type {
typedef typename mpl::has_key<typename options<Eq>::type, Opt>::type type;
};
template<typename cs, typename T>
struct seq_has_option {
typedef typename mpl::transform<cs, has_option<mpl::_1, T> >::type bool_seq;
typedef typename mpl::not_<boost::is_same<typename mpl::find<bool_seq, mpl::true_>::type, mpl::end<bool_seq> > >::type type;
};
template<typename seq, typename Derived>
struct constraint_sequence : public seq {
template<typename T>
void pretty(T type) {
std::cout<<"pretty: "<<__PRETTY_FUNCTION__<<std::endl;
};
//don't allow expression equation stacking: the compile time impact is huge if we want to allow
//text parsing
/*
//an equation gets added to this sequence
template<typename T>
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<seq, T>::type >::type operator &(T& val);
//an sequence gets added to this sequence (happens only if sequenced equations like coincident are used)
template<typename T>
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, seq>::type >::type operator &(T& val);
*/
//we also allow to set values directly into the equation, as this makes it more compftable for multi constraints
//as align. Note that this only works if all option types of all equations in this sequence are distinguishable
template<typename T>
typename boost::enable_if<typename seq_has_option<seq, T>::type, Derived&>::type
operator=(const T& val) {
fusion::filter_view<constraint_sequence, has_option<mpl::_, T > > view(*this);
fusion::front(view) = val;
return *((Derived*)this);
};
};
/*
template<typename T>
struct get_equation_id {
typedef typename T::ID type;
};
template<typename Seq, typename T>
struct pushed_seq {
typedef typename mpl::if_<mpl::is_sequence<Seq>, Seq, fusion::vector1<Seq> >::type S1;
typedef typename mpl::if_<mpl::is_sequence<T>, T, fusion::vector1<T> >::type S2;
typedef typename mpl::fold< S2, S1, mpl::if_< boost::is_same<
mpl::find<mpl::_1, mpl::_2>, mpl::end<mpl::_1> >, mpl::push_back<mpl::_1,mpl::_2>, mpl::_1> >::type unique_vector;
typedef typename mpl::sort<unique_vector, mpl::less< get_equation_id<mpl::_1>, get_equation_id<mpl::_2> > >::type sorted_vector;
typedef typename fusion::result_of::as_vector< sorted_vector >::type vec;
typedef constraint_sequence<vec> type;
};*/
template<typename Derived, typename Option, int id, AccessType a = general>
struct Equation : public EQ {
typedef typename mpl::if_<mpl::is_sequence<Option>, Option, mpl::vector<Option> >::type option_sequence;
typedef typename mpl::fold<option_sequence, fusion::map<>, fusion::result_of::push_back<mpl::_1, fusion::pair<mpl::_2, std::pair<bool, mpl::_2> > > > ::type option_set_map;
typedef typename fusion::result_of::as_map<option_set_map>::type options;
options values;
AccessType access;
typedef mpl::int_<id> ID;
Equation() : access(a) {};
//assign option
template<typename T>
typename boost::enable_if<fusion::result_of::has_key<options, T>, Derived&>::type operator()(const T& val) {
fusion::at_key<T>(values).second = val;
fusion::at_key<T>(values).first = true;
return *(static_cast<Derived*>(this));
};
//assign option
template<typename T>
typename boost::enable_if<fusion::result_of::has_key<options, T>, Derived&>::type operator=(const T& val) {
return operator()(val);
};
//assign complete equation (we need to override the operator= in the derived class anyway as it
//is automatically created by the compiler, so we use a different name here to avoid duplicate
//operator= warning on msvc)
Derived& assign(const Derived& eq);
//don't allow expression equation stacking: the compile time impact is huge if we want to allow
//text parsing
/*
//an equation gets added to this equation
template<typename T>
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<T, Derived>::type >::type operator &(T& val);
//an sequence gets added to this equation (happens only if sequenced equations like coincident are used)
template<typename T>
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, Derived>::type >::type operator &(T& val);
*/
//set default option values, needed for repeatability and to prevent unexpected behaviour
virtual void setDefault() {};
};
template <typename charT, typename traits, typename Eq>
typename boost::enable_if<boost::is_base_of<EQ, Eq>, std::basic_ostream<charT,traits>&>::type
operator << (std::basic_ostream<charT,traits>& stream, const Eq& equation);
struct Distance : public Equation<Distance, mpl::vector2<double, SolutionSpace>, 1 > {
using Equation::operator=;
using Equation::options;
Distance() {
setDefault();
};
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Distance& operator=(const Distance& d) {
return Equation::assign(d);
};
void setDefault() {};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type {
type() {
throw constraint_error() << boost::errinfo_errno(100) << error_message("unsupported geometry in distance constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
options values;
//template definition
template <typename DerivedA,typename DerivedB>
void calculatePseudo(const E::MatrixBase<DerivedA>& param1, Vec& v1, const E::MatrixBase<DerivedB>& param2, Vec& v2) {
assert(false);
};
void setScale(Scalar scale) {
assert(false);
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
struct Orientation : public Equation<Orientation, Direction, 2, rotation> {
using Equation::operator=;
using Equation::options;
Orientation() {
setDefault();
};
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Orientation& operator=(const Orientation& d) {
return Equation::assign(d);
};
void setDefault() {
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(101) << error_message("unsupported geometry in orientation constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
options values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
struct Angle : public Equation<Angle, mpl::vector2<double, SolutionSpace>, 3, rotation> {
using Equation::operator=;
Angle() {
setDefault();
};
//override needed ass assignmend operator is always created by the compiler
//and we need to ensure that our custom one is used
Angle& operator=(const Angle& d) {
return Equation::assign(d);
};
void setDefault() {
fusion::at_key<double>(values) = std::make_pair(false, 0.);
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(102) << error_message("unsupported geometry in angle constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
options values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
//static is needed to restrain the scope of the objects to the current compilation unit. Without it
//every compiled file including this header would define these as global and the linker would find
//multiple definitions of the same objects
static Distance distance;
static Orientation orientation;
static Angle angle;
};
#ifndef DCM_EXTERNAL_CORE
#include "imp/equations_imp.hpp"
#endif
#endif //GCM_EQUATIONS_H

View File

@@ -1,352 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GEOMETRY_H
#define GCM_GEOMETRY_H
#include <iostream>
#include <Eigen/Core>
#include <boost/type_traits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/variant.hpp>
#include "traits.hpp"
#include "logging.hpp"
#include "transformation.hpp"
namespace mpl = boost::mpl;
namespace dcm {
//signal we use for recalculation
struct recalculated {};
//all supported geometry types for easy access and comparison
namespace geometry {
enum types {
parameter = 0,
direction,
point,
line,
segment,
circle,
arc,
geometry,
ellipse,
elliptical_arc,
plane,
cylinder
};
}//namespace geometry
namespace tag {
struct undefined {
typedef mpl::int_<0> parameters;
typedef mpl::int_<0> transformations;
};
//we need to order tags, this values make it easy for module tags
namespace weight {
struct parameter : mpl::int_<geometry::parameter> {};
struct direction : mpl::int_<geometry::direction> {};
struct point : mpl::int_<geometry::point> {};
struct line : mpl::int_<geometry::line> {};
struct segment : mpl::int_<geometry::segment> {};
struct circle : mpl::int_<geometry::circle> {};
struct arc : mpl::int_<geometry::arc> {};
struct ellipse : mpl::int_<geometry::ellipse> {};
struct elliptical_arc : mpl::int_<geometry::elliptical_arc> {};
struct plane : mpl::int_<geometry::plane> {};
struct cylinder : mpl::int_<geometry::cylinder> {};
}
} // tag
namespace details {
struct bg {}; //struct to allow test for basic geometry
template< typename weight_type, int params, bool rotatable, bool translatable>
struct basic_geometry : public bg {
typedef mpl::int_<params> parameters;
typedef typename mpl::if_c<translatable, mpl::int_<1>, mpl::int_<0> >::type translations;
typedef typename mpl::if_c<rotatable, mpl::int_<1>, mpl::int_<0> >::type rotations;
typedef weight_type weight;
typedef mpl::vector0<> sub_stack;
};
//build up stacked geometry. these are geometries which can be split into multiple basic geometries. For
//example lines can be splittet into a point and a direction. Make sure you order the basic geometry in a
//sensible rotation/translation manner. Remember: geometry is first rotated, than translated. Therefore
//everything that gets rotated and translated needs to be first, than the rotation only stuff, then the
//untransformed. For a line this would be <point, direction>
template<typename weight_type, typename T1, typename T2>
struct stacked2_geometry {
//be sure we only stack base geometries
BOOST_MPL_ASSERT((boost::is_base_of< bg, T1 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T2 >));
typedef typename mpl::plus<typename T1::parameters, typename T2::parameters>::type parameters;
typedef typename mpl::plus<typename T1::rotations, typename T2::rotations>::type rotations;
typedef typename mpl::plus<typename T1::translations, typename T2::translations>::type translations;
typedef weight_type weight;
typedef mpl::vector2<T1, T2> sub_stack;
};
template<typename weight_type, typename T1, typename T2, typename T3>
struct stacked3_geometry {
//be sure we only stack base geometries
BOOST_MPL_ASSERT((boost::is_base_of< bg, T1 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T2 >));
BOOST_MPL_ASSERT((boost::is_base_of< bg, T3 >));
typedef typename mpl::plus<typename T1::parameters, typename T2::parameters, typename T3::parameters>::type parameters;
typedef typename mpl::plus<typename T1::rotations, typename T2::rotations, typename T3::rotations>::type rotations;
typedef typename mpl::plus<typename T1::translations, typename T2::translations, typename T3::translations>::type translations;
typedef weight_type weight;
typedef mpl::vector3<T1, T2, T3> sub_stack;
};
} //details
namespace tag {
//a parameter is universal, so let's define it here
struct parameter : details::basic_geometry<weight::parameter, 1, false, false> {};
} //tag
struct orderd_bracket_accessor {
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
return t[ID];
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
t[ID] = value;
};
};
struct orderd_roundbracket_accessor {
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
return t(ID);
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
t(ID) = value;
};
};
//tag ordering (smaller weight is first tag)
template<typename T1, typename T2>
struct tag_order {
BOOST_MPL_ASSERT((mpl::not_< mpl::or_<
boost::is_same< typename T1::weight, mpl::int_<0> >,
boost::is_same< typename T2::weight, mpl::int_<0> > > >));
typedef typename mpl::less<typename T2::weight, typename T1::weight>::type swapt;
typedef typename mpl::if_<swapt, T2, T1>::type first_tag;
typedef typename mpl::if_<swapt, T1, T2>::type second_tag;
};
//template<typename T1, typename T2>
//struct type_order : public tag_order< typename geometry_traits<T1>::tag, typename geometry_traits<T2>::tag > {};
template< typename T>
struct geometry_traits {
BOOST_MPL_ASSERT_MSG(false, NO_GEOMETRY_TRAITS_SPECIFIED_FOR_TYPE, (T));
};
template< typename T>
struct geometry_clone_traits {
T operator()(T& val) {
return T(val);
};
};
namespace details {
// the parameter a geometr needs in a mapped equation system need to be managed separate, as
// we may want to access the same parameter space from different geometries (if they are linked)
// this is done by the parameter space class
template<typename Kernel>
struct parameter_space {
void init(typename Kernel::MappedEquationSystem* mes);
};
template<typename Kernel, int Dim, typename TagList = mpl::vector0<> >
class Geometry {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::DynStride DS;
typedef typename Kernel::template transform_type<Dim>::type Transform;
typedef typename Kernel::template transform_type<Dim>::diff_type DiffTransform;
#ifdef USE_LOGGING
protected:
dcm_logger log;
#endif
public:
typedef mpl::int_<Dim> Dimension;
Geometry();
//basic ations
template<typename tag, typename Derived>
void setValue(const Eigen::MatrixBase<Derived>& t) {
init<tag>();
m_global = t;
};
typename Kernel::Vector& getValue() {
return m_global;
};
void transform(const Transform& t);
geometry::types getGeometryType() {
return geometry::types(m_general_type);
};
int getExactType() {
return m_exact_type;
};
//allow accessing the internal values in unittests without making them public,
//so that access control of the internal classes is not changed and can be tested
#ifdef TESTING
typename Kernel::Vector& toplocal() {
return m_toplocal;
};
typename Kernel::Vector& rotated() {
return m_rotated;
};
int& offset() {
return m_offset;
};
void clusterMode(bool iscluster, bool isFixed) {
setClusterMode(iscluster, isFixed);
};
void trans(const Transform& t) {
transform(t);
};
void recalc(DiffTransform& trans) {
recalculate(trans);
};
typename Kernel::Vector3 point() {
return getPoint();
};
int parameterCount() {
return m_parameterCount;
};
template<typename T>
void test_linkTo(std::shared_ptr< Geometry< Kernel, Dim > > geom, int offset) {
linkTo<T>(geom, offset);
};
bool test_isLinked() {
return isLinked();
};
#endif
//protected would be the right way, however, visual studio 10 does not find a way to access them even when constraint::holder structs
//are declared friend
//protected:
int m_general_type, m_exact_type; //hold the type numbers for easy identification
int m_BaseParameterCount; //count of the parameters the variant geometry type needs
int m_parameterCount; //count of the used parameters (when in cluster:6, else m_BaseParameterCount)
int m_offset, m_offset_rot; //the starting point of our parameters in the math system parameter vector
int m_rotations; //count of rotations to be done when original vector gets rotated
int m_translations; //count of translations to be done when original vector gets rotated
bool m_isInCluster, m_clusterFixed, m_init;
typename Kernel::Vector m_toplocal; //the local value in the toplevel cluster used for cuttent solving
typename Kernel::Vector m_global; //the global value outside of all clusters
typename Kernel::Vector m_rotated; //the global value as the rotation of toplocal (used as temp)
typename Kernel::Matrix m_diffparam; //gradient vectors combined as matrix when in cluster
typename Kernel::VectorMap m_parameter; //map to the parameters in the solver
template<typename tag>
void init();
void normalize();
typename Kernel::VectorMap& getParameterMap();
void initMap(typename Kernel::MappedEquationSystem* mes);
bool isInitialised() {
return m_init;
};
void setClusterMode(bool iscluster, bool isFixed);
bool getClusterMode() {
return m_isInCluster;
};
bool isClusterFixed() {
return m_clusterFixed;
};
int m_link_offset;
std::shared_ptr<Geometry<Kernel, Dim, TagList> > m_link;
template<typename T>
void linkTo(std::shared_ptr< Geometry< Kernel, Dim, TagList > > geom, int offset);
bool isLinked() {
return m_link!=0;
};
void recalculate(DiffTransform& trans);
typename Kernel::Vector3 getPoint() {
return m_toplocal.template segment<Dim>(0);
};
//use m_value or parametermap as new value, depending on the solving mode
void finishCalculation();
template<typename VectorType>
void transform(const Transform& t, VectorType& vec);
void scale(Scalar value);
//let the derived class decide what happens on significant events
virtual void reset() = 0;
virtual void recalculated() = 0;
virtual void removed() = 0;
};
} //details
} //dcm
#ifndef DCM_EXTERNAL_CORE
#include "imp/geometry_imp.hpp"
#endif
#endif // GCM_GEOMETRY_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,453 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CONSTRAINT_HOLDER_IMP_H
#define DCM_CONSTRAINT_HOLDER_IMP_H
#include "opendcm/core/constraint.hpp"
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
namespace detail {
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::OptionSetter::OptionSetter(Objects& val) : objects(val) {};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template<typename T>
typename boost::enable_if<typename Constraint<Sys, Dim>::template holder<ConstraintVector, tag1, tag2>::template has_option<T>::type, void>::type
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::OptionSetter::operator()(EquationSet<T>& val) const {
//get the index of the corresbonding equation
typedef typename mpl::find<EquationVector, T>::type iterator;
typedef typename mpl::distance<typename mpl::begin<EquationVector>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<EquationVector>::type > >));
fusion::copy(fusion::at<distance>(objects).values, val.m_eq.values);
val.access = fusion::at<distance>(objects).access;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template<typename T>
typename boost::enable_if<mpl::not_<typename Constraint<Sys, Dim>::template holder<ConstraintVector, tag1, tag2>::template has_option<T>::type>, void>::type
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::OptionSetter::operator()(EquationSet<T>& val) const {
typedef typename mpl::find<EquationVector, T>::type iterator;
typedef typename mpl::distance<typename mpl::begin<EquationVector>::type, iterator>::type distance;
val.access = fusion::at<distance>(objects).access;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::Calculator::Calculator(geom_ptr f, geom_ptr s, Scalar sc, AccessType a)
: first(f), second(s), scale(sc), access(a) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::Calculator::operator()(T& val) const {
//if the equation is disabled we don't have anything mapped so avoid accessing it
if(!val.enabled)
return;
//if we are not one of the accessed types we don't need to be recalculated
if((access==rotation && val.access!=rotation)
|| (access == general && val.access != general)) {
val.m_residual(0) = 0;
if(first->getClusterMode()) {
if(!first->isClusterFixed()) {
val.m_diff_first_rot.setZero();
val.m_diff_first.setZero();
}
}
else
val.m_diff_first.setZero();
if(second->getClusterMode()) {
if(!second->isClusterFixed()) {
val.m_diff_second_rot.setZero();
val.m_diff_second.setZero();
}
}
else
val.m_diff_second.setZero();
}
//we need to calculate, so lets go for it!
else {
val.m_eq.setScale(scale);
val.m_residual(0) = val.m_eq.calculate(first->m_parameter, second->m_parameter);
//now see which way we should calculate the gradient (may be different for both geometries)
if(first->m_parameterCount) {
if(first->getClusterMode()) {
//when the cluster is fixed no maps are set as no parameters exist.
if(!first->isClusterFixed()) {
//cluster mode, so we do a full calculation with all 3 rotation diffparam vectors
for(int i=0; i<3; i++) {
val.m_diff_first_rot(i) = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, first->m_diffparam.col(i));
}
//and now with the translations
for(int i=0; i<3; i++) {
val.m_diff_first(i) = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, first->m_diffparam.col(i+3));
}
}
}
else {
//not in cluster, so allow the constraint to optimize the gradient calculation
val.m_eq.calculateGradientFirstComplete(first->m_parameter, second->m_parameter, val.m_diff_first);
}
}
if(second->m_parameterCount) {
if(second->getClusterMode()) {
if(!second->isClusterFixed()) {
//cluster mode, so we do a full calculation with all 3 rotation diffparam vectors
for(int i=0; i<3; i++) {
val.m_diff_second_rot(i) = val.m_eq.calculateGradientSecond(first->m_parameter,
second->m_parameter, second->m_diffparam.col(i));
}
//and the translation separated
for(int i=0; i<3; i++) {
val.m_diff_second(i) = val.m_eq.calculateGradientSecond(first->m_parameter,
second->m_parameter, second->m_diffparam.col(i+3));
}
}
}
else {
//not in cluster, so allow the constraint to optimize the gradient calculation
val.m_eq.calculateGradientSecondComplete(first->m_parameter, second->m_parameter, val.m_diff_second);
}
}
}
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::MapSetter::MapSetter(MES& m, geom_ptr f, geom_ptr s)
: mes(m), first(f), second(s) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::MapSetter::operator()(T& val) const {
if(!val.enabled)
return;
//when in cluster, there are 6 clusterparameter we differentiat for, if not we differentiat
//for every parameter in the geometry;
int equation = mes.setResidualMap(val.m_residual, val.access);
if(first->getClusterMode()) {
if(!first->isClusterFixed()) {
mes.setJacobiMap(equation, first->m_offset_rot, 3, val.m_diff_first_rot);
mes.setJacobiMap(equation, first->m_offset, 3, val.m_diff_first);
}
}
else
mes.setJacobiMap(equation, first->m_offset, first->m_parameterCount, val.m_diff_first);
if(second->getClusterMode()) {
if(!second->isClusterFixed()) {
mes.setJacobiMap(equation, second->m_offset_rot, 3, val.m_diff_second_rot);
mes.setJacobiMap(equation, second->m_offset, 3, val.m_diff_second);
}
}
else
mes.setJacobiMap(equation, second->m_offset, second->m_parameterCount, val.m_diff_second);
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::PseudoCollector::PseudoCollector(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2)
: first(f), second(s), points1(vec1), points2(vec2) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::PseudoCollector::operator()(T& val) const {
if(!val.enabled)
return;
if(first->m_isInCluster && second->m_isInCluster) {
val.m_eq.calculatePseudo(first->m_rotated, points1, second->m_rotated, points2);
}
else if(first->m_isInCluster) {
typename Kernel::Vector sec = second->m_parameter;
val.m_eq.calculatePseudo(first->m_rotated, points1, sec, points2);
}
else if(second->m_isInCluster) {
typename Kernel::Vector fir = first->m_parameter;
val.m_eq.calculatePseudo(fir, points1, second->m_rotated, points2);
}
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::LGZ::LGZ(geom_ptr f, geom_ptr s)
: first(f), second(s) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::LGZ::operator()(T& val) const {
typedef typename Sys::Kernel Kernel;
if(!val.enabled)
return;
//to treat local gradient zeros we calculate a approximate second derivative of the equations
//only do that if neseccary: residual is not zero
if(!Kernel::isSame(val.m_residual(0),0, 1e-7)) { //TODO: use exact precision and scale value
//rotations exist only in cluster
if(first->getClusterMode() && !first->isClusterFixed()) {
//LGZ exists for rotations only
for(int i=0; i<3; i++) {
//only treat if the gradient really is zero
if(Kernel::isSame(val.m_diff_first_rot(i), 0, 1e-7)) {
//to get the approximated second derivative we need the slightly moved geometry
const typename Kernel::Vector p_old = first->m_parameter;
first->m_parameter += first->m_diffparam.col(i)*1e-3;
first->normalize();
//with this changed geometry we test if a gradient exist now
typename Kernel::VectorMap block(&first->m_diffparam(0,i),first->m_parameterCount,1, DS(1,1));
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, block);
first->m_parameter = p_old;
//let's see if the initial LGZ was a real one
if(!Kernel::isSame(res, 0, 1e-7)) {
//is a fake zero, let's correct it
val.m_diff_first_rot(i) = res;
};
};
};
}
//and the same for the second one too
if(second->getClusterMode() && !second->isClusterFixed()) {
for(int i=0; i<3; i++) {
//only treat if the gradient really is zero
if(Kernel::isSame(val.m_diff_second_rot(i), 0, 1e-7)) {
//to get the approximated second derivative we need the slightly moved geometry
const typename Kernel::Vector p_old = second->m_parameter;
second->m_parameter += second->m_diffparam.col(i)*1e-3;
second->normalize();
//with this changed geometry we test if a gradient exist now
typename Kernel::VectorMap block(&second->m_diffparam(0,i),second->m_parameterCount,1, DS(1,1));
typename Kernel::number_type res = val.m_eq.calculateGradientFirst(first->m_parameter,
second->m_parameter, block);
second->m_parameter = p_old;
//let's see if the initial LGZ was a real one
if(!Kernel::isSame(res, 0, 1e-7)) {
//is a fake zero, let's correct it
val.m_diff_second_rot(i) = res;
};
};
};
};
};
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::GenericEquations::GenericEquations(std::vector<boost::any>& v)
: vec(v) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::GenericEquations::operator()(T& val) const {
vec.push_back(val.m_eq);
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::GenericConstraints::GenericConstraints(std::vector<boost::any>& v)
: vec(v) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::GenericConstraints::operator()(T& val) const {
vec.push_back(val);
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::Types::Types(std::vector<const std::type_info*>& v)
: vec(v) {
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
template< typename T >
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::Types::operator()(T& val) const {
vec.push_back(&typeid(T));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::holder(Objects& obj) : m_objects(obj) {
//set the initial values in the equations
fusion::for_each(m_sets, OptionSetter(obj));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::calculate(geom_ptr first, geom_ptr second,
Scalar scale, AccessType access) {
fusion::for_each(m_sets, Calculator(first, second, scale, access));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::treatLGZ(geom_ptr first, geom_ptr second) {
fusion::for_each(m_sets, LGZ(first, second));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
typename Constraint<Sys, Dim>::placeholder*
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::resetConstraint(geom_ptr first, geom_ptr second) const {
//boost::apply_visitor(creator, first->m_geometry, second->m_geometry);
//if(creator.need_swap) first.swap(second);
return NULL;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::setMaps(MES& mes, geom_ptr first, geom_ptr second) {
fusion::for_each(m_sets, MapSetter(mes, first, second));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2) {
fusion::for_each(m_sets, PseudoCollector(f, s, vec1, vec2));
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
typename Constraint<Sys, Dim>::placeholder*
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::clone() {
return new holder(*this);
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
int Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::equationCount() {
int count = 0;
EquationCounter counter(count);
fusion::for_each(m_sets, counter);
return count;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
std::vector<boost::any>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::getGenericEquations() {
std::vector<boost::any> vec;
fusion::for_each(m_sets, GenericEquations(vec));
return vec;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
std::vector<boost::any>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::getGenericConstraints() {
std::vector<boost::any> vec;
fusion::for_each(m_objects, GenericConstraints(vec));
return vec;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
std::vector<const std::type_info*>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::getEquationTypes() {
std::vector<const std::type_info*> vec;
mpl::for_each< EquationVector >(Types(vec));
return vec;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
std::vector<const std::type_info*>
Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::getConstraintTypes() {
std::vector<const std::type_info*> vec;
mpl::for_each< ConstraintVector >(Types(vec));
return vec;
};
template<typename Sys, int Dim>
template<typename ConstraintVector, typename tag1, typename tag2>
void Constraint<Sys, Dim>::holder<ConstraintVector, tag1, tag2>::disable() {
fusion::for_each(m_sets, disabler());
};
};//detail
};//dcm
#endif //GCM_CONSTRAINT_H

View File

@@ -1,208 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CONSTRAINT_IMP_H
#define DCM_CONSTRAINT_IMP_H
#include "../constraint.hpp"
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/size.hpp>
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
namespace detail {
template<typename Sys, int Dim>
template<typename ConstraintVector>
void Constraint<Sys, Dim>::initialize(ConstraintVector& cv) {
//use the compile time unrolling to retrieve the geometry tags
initializeFirstGeometry<mpl::int_<0> >(cv, mpl::true_());
};
template<typename Sys, int Dim>
template<typename WhichType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFirstGeometry(ConstraintVector& cv, boost::mpl::false_ /*unrolled*/) {
//this function is only for breaking the compilation loop, it should never be called
BOOST_ASSERT(false); //Should never assert here; only meant to stop recursion at the end of the typelist
};
template<typename Sys, int Dim>
template<typename WhichType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFirstGeometry(ConstraintVector& cv, boost::mpl::true_ /*unrolled*/) {
typedef typename Sys::geometries geometries;
switch(first->getExactType()) {
#ifdef BOOST_PP_LOCAL_ITERATE
#define BOOST_PP_LOCAL_MACRO(n) \
case (WhichType::value + n): \
return initializeSecondGeometry<boost::mpl::int_<0>,\
typename mpl::at<geometries, typename in_range_value<geometries, WhichType::value + n>::type >::type,\
ConstraintVector>(cv, typename boost::mpl::less<boost::mpl::int_<WhichType::value + n>, boost::mpl::size<geometries> >::type()); \
break;
#define BOOST_PP_LOCAL_LIMITS (0, 10)
#include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_PP_LOCAL_ITERATE
default:
typedef typename mpl::int_<WhichType::value + 10> next_which_t;
return initializeFirstGeometry<next_which_t, ConstraintVector> (cv,
typename mpl::less< next_which_t, typename mpl::size<geometries>::type >::type());
}
};
template<typename Sys, int Dim>
template<typename WhichType, typename FirstType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeSecondGeometry(ConstraintVector& cv, boost::mpl::false_ /*unrolled*/) {
//this function is only for breaking the compilation loop, it should never be called
BOOST_ASSERT(false); //Should never assert here; only meant to stop recursion at the end of the typelist
};
template<typename Sys, int Dim>
template<typename WhichType, typename FirstType, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeSecondGeometry(ConstraintVector& cv, boost::mpl::true_ /*unrolled*/) {
typedef typename Sys::geometries geometries;
switch(second->getExactType()) {
#ifdef BOOST_PP_LOCAL_ITERATE
#define BOOST_PP_LOCAL_MACRO(n) \
case (WhichType::value + n): \
return intitalizeFinalize<FirstType, \
typename mpl::at<geometries, typename in_range_value<geometries, WhichType::value + n>::type >::type,\
ConstraintVector>(cv, typename boost::mpl::less<boost::mpl::int_<WhichType::value + n>, boost::mpl::size<geometries> >::type()); \
break;
#define BOOST_PP_LOCAL_LIMITS (0, 10)
#include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_PP_LOCAL_ITERATE
default:
typedef typename mpl::int_<WhichType::value + 10> next_which_t;
return initializeSecondGeometry<next_which_t, FirstType, ConstraintVector>
(cv, typename mpl::less
< next_which_t
, typename mpl::size<geometries>::type>::type()
);
}
};
template<typename Sys, int Dim>
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void Constraint<Sys, Dim>::intitalizeFinalize(ConstraintVector& cv, boost::mpl::true_ /*is_unrolled_t*/) {
initializeFromTags<FirstType, SecondType>(cv);
};
template<typename Sys, int Dim>
template<typename FirstType, typename SecondType, typename ConstraintVector>
inline void Constraint<Sys, Dim>::intitalizeFinalize(ConstraintVector& cv, boost::mpl::false_ /*is_unrolled_t*/) {
//Should never be here at runtime; only required to block code generation that deref's the sequence out of bounds
BOOST_ASSERT(false);
}
template<typename Sys, int Dim>
template<typename tag1, typename tag2, typename ConstraintVector>
void Constraint<Sys, Dim>::initializeFromTags(ConstraintVector& v) {
typedef tag_order< tag1, tag2 > order;
//and build the placeholder
content = new holder<ConstraintVector, typename order::first_tag, typename order::second_tag >(v);
//geometry order needs to be the one needed by equations
if(order::swapt::value)
first.swap(second);
};
template<typename Sys, int Dim>
Constraint<Sys, Dim>::Constraint(geom_ptr f, geom_ptr s)
: first(f), second(s), content(0) {
//cf = first->template connectSignal<reset> (boost::bind(&Constraint::geometryReset, this, _1));
//cs = second->template connectSignal<reset> (boost::bind(&Constraint::geometryReset, this, _1));
};
template<typename Sys, int Dim>
Constraint<Sys, Dim>::~Constraint() {
delete content;
//first->template disconnectSignal<reset>(cf);
//second->template disconnectSignal<reset>(cs);
};
template<typename Sys, int Dim>
int Constraint<Sys, Dim>::equationCount() {
return content->equationCount();
};
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::calculate(Scalar scale, AccessType access) {
content->calculate(first, second, scale, access);
};
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::treatLGZ() {
content->treatLGZ(first, second);
};
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::setMaps(MES& mes) {
content->setMaps(mes, first, second);
};
template<typename Sys, int Dim>
void Constraint<Sys, Dim>::collectPseudoPoints(Vec& vec1, Vec& vec2) {
content->collectPseudoPoints(first, second, vec1, vec2);
};
template<typename Sys, int Dim>
std::vector<boost::any> Constraint<Sys, Dim>::getGenericEquations() {
return content->getGenericEquations();
};
template<typename Sys, int Dim>
std::vector<boost::any> Constraint<Sys, Dim>::getGenericConstraints() {
return content->getGenericConstraints();
};
template<typename Sys, int Dim>
std::vector<const std::type_info*> Constraint<Sys, Dim>::getEquationTypes() {
return content->getEquationTypes();
};
template<typename Sys, int Dim>
std::vector<const std::type_info*> Constraint<Sys, Dim>::getConstraintTypes() {
return content->getConstraintTypes();
};
};//detail
};//dcm
#endif //GCM_CONSTRAINT_H

View File

@@ -1,250 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EQUATIONS_IMP_H
#define DCM_EQUATIONS_IMP_H
#include <assert.h>
#include "../equations.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/iterator_range.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/fusion/include/advance.hpp>
#include <boost/fusion/include/back.hpp>
#include <boost/fusion/include/iterator_range.hpp>
#include <boost/fusion/include/nview.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/as_map.hpp>
#include <boost/fusion/include/filter_view.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/exception/exception.hpp>
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
namespace dcm {
template<typename Seq, typename T>
struct pushed_seq;
/*
template<typename seq>
template<typename T>
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<seq, T>::type >::type
constraint_sequence<seq>::operator &(T& val) {
typedef typename pushed_seq<seq, T>::type Sequence;
//create the new sequence
Sequence vec;
//get a index vector for this sequence
typedef typename mpl::transform<typename pushed_seq<seq, T>::S1,
fusion::result_of::distance<typename fusion::result_of::begin<Sequence>::type,
fusion::result_of::find<Sequence, mpl::_1> > >::type position_vector_added;
//and copy the types in
fusion::nview<Sequence, position_vector_added> view_added(vec);
fusion::copy(*this, view_added);
//insert this object at the end of the sequence
*fusion::find<T>(vec) = val;
//and return our new extended sequence
return vec;
};
template<typename seq>
template<typename T>
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, seq>::type >::type
constraint_sequence<seq>::operator &(T& val) {
typedef typename pushed_seq<T, seq>::type Sequence;
//create the new sequence
Sequence vec;
//get a index vector for the added sequence
typedef typename mpl::transform<typename pushed_seq<T, seq>::S1,
fusion::result_of::distance<typename fusion::result_of::begin<Sequence>::type,
fusion::result_of::find<Sequence, mpl::_1> > >::type position_vector_added;
//and copy the types in
fusion::nview<Sequence, position_vector_added> view_added(vec);
fusion::copy(val, view_added);
//to copy the types of the second sequence is not as easy as before. If types were already present in
//the original sequence they are not added again. therefore we need to find all types of the second sequence
//in the new one and assign the objects to this positions.
//get a index vector for all second-sequence-elements
typedef typename mpl::transform<typename pushed_seq<T, seq>::S2,
fusion::result_of::distance<typename fusion::result_of::begin<Sequence>::type,
fusion::result_of::find<Sequence, mpl::_1> > >::type position_vector;
//and copy the types in
fusion::nview<Sequence, position_vector> view(vec);
fusion::copy(*this, view);
//and return our new extended sequence
return vec;
};
*/
template<typename options>
struct option_copy {
options* values;
option_copy(options& op) : values(&op) {};
template<typename T>
void operator()(const T& val) const {
if(val.second.first)
fusion::at_key<typename T::first_type>(*values) = val.second;
};
};
template<typename Derived, typename Option, int id, AccessType a >
Derived& Equation<Derived, Option, id, a>::assign(const Derived& eq) {
//we only copy the values which were set and are therefore valid
option_copy<options> oc(values);
fusion::for_each(eq.values, oc);
//the assigned equation can be set back to default for convenience in further usage
const_cast<Derived*>(&eq)->setDefault();
return *static_cast<Derived*>(this);
};
/*
template<typename Derived, typename Option, int id, AccessType a >
template<typename T>
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<T, Derived>::type >::type
Equation<Derived, Option, id, a>::operator &(T& val) {
typename pushed_seq<T, Derived>::type vec;
*fusion::find<T>(vec) = val;
*fusion::find<Derived>(vec) = *(static_cast<Derived*>(this));
return vec;
};
template<typename Derived, typename Option, int id, AccessType a >
template<typename T>
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, Derived>::type >::type
Equation<Derived, Option, id, a>::operator &(T& val) {
typedef typename pushed_seq<T, Derived>::type Sequence;
//create the new sequence
Sequence vec;
//get a index vector for the added sequence
typedef typename mpl::transform<typename pushed_seq<T, Derived>::S1,
fusion::result_of::distance<typename fusion::result_of::begin<Sequence>::type,
fusion::result_of::find<Sequence, mpl::_1> > >::type position_vector;
//and copy the types in
fusion::nview<Sequence, position_vector> view(vec);
fusion::copy(val, view);
//insert this object into the sequence
*fusion::find<Derived>(vec) = *static_cast<Derived*>(this);
//and return our new extended sequence
return vec;
};
*/
//convenience stream functions for debugging
template <typename charT, typename traits>
struct print_pair {
std::basic_ostream<charT,traits>* stream;
template<typename T>
void operator()(const T& t) const {
*stream << "("<<t.second.first << ", "<<t.second.second<<") ";
};
};
template <typename charT, typename traits, typename Eq>
typename boost::enable_if<boost::is_base_of<EQ, Eq>, std::basic_ostream<charT,traits>&>::type
operator << (std::basic_ostream<charT,traits>& stream, const Eq& equation)
{
print_pair<charT, traits> pr;
pr.stream = &stream;
stream << typeid(equation).name() << ": ";
fusion::for_each(equation.values, pr);
return stream;
}
/*
Distance::Distance() : Equation() {
setDefault();
};
Distance& Distance::operator=(const Distance& d) {
return Equation::assign(d);
};
void Distance::setDefault() {};
Orientation::Orientation() : Equation() {
setDefault();
};
Orientation& Orientation::operator=(const Orientation& d) {
return Equation::assign(d);
};
void Orientation::setDefault() {
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
};
Angle::Angle() : Equation() {
setDefault();
};
Angle& Angle::operator=(const Angle& d) {
return Equation::assign(d);
};
void Angle::setDefault() {
fusion::at_key<double>(values) = std::make_pair(false, 0.);
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
};
*/
};
#endif //GCM_EQUATIONS_H

View File

@@ -1,266 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GEOMETRY_IMP_H
#define GCM_GEOMETRY_IMP_H
#include <iostream>
#include "../geometry.hpp"
#include <Eigen/Core>
#include <boost/type_traits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/find.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/concept_check.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/function.hpp>
#include <boost/variant.hpp>
#ifdef USE_LOGGING
#include <boost/math/special_functions.hpp>
#endif
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
namespace details {
template< typename Kernel, int Dim, typename TagList>
Geometry<Kernel, Dim, TagList>::Geometry()
: m_isInCluster(false), m_parameter(NULL,0,DS(0,0)),
m_clusterFixed(false), m_init(false) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry"));
#endif
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::transform(const Transform& t) {
if(m_isInCluster)
transform(t, m_toplocal);
else
if(m_init)
transform(t, m_rotated);
else
transform(t, m_global);
};
template< typename Kernel, int Dim, typename TagList>
template<typename tag>
void Geometry<Kernel, Dim, TagList>::init() {
m_BaseParameterCount = tag::parameters::value;
m_parameterCount = m_BaseParameterCount;
m_rotations = tag::rotations::value;
m_translations = tag::translations::value;
m_toplocal.setZero(m_parameterCount);
m_global.resize(m_parameterCount);
m_rotated.resize(m_parameterCount);
m_rotated.setZero();
m_diffparam.resize(m_parameterCount,6);
m_diffparam.setZero();
m_general_type = tag::weight::value;
m_exact_type = mpl::find<TagList, tag>::type::pos::value;
normalize();
//new value which is not set into parameter, so init is false
m_init = false;
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, information) << "Init: "<<m_global.transpose();
#endif
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::normalize() {
//directions are not necessarily normalized, but we need to ensure this in cluster mode
for(int i=m_translations; i!=m_rotations; i++)
m_global.template segment<Dim>(i*Dim).normalize();
};
template< typename Kernel, int Dim, typename TagList>
typename Kernel::VectorMap& Geometry<Kernel, Dim, TagList>::getParameterMap() {
m_isInCluster = false;
m_parameterCount = m_BaseParameterCount;
return m_parameter;
};
template< typename Kernel, int Dim, typename TagList>
template<typename T>
void Geometry<Kernel, Dim, TagList>::linkTo(std::shared_ptr<Geometry<Kernel, Dim, TagList> > geom, int offset) {
init<T>();
m_link = geom;
m_link_offset = offset;
m_global = geom->m_global.segment(offset, m_BaseParameterCount);
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::initMap(typename Kernel::MappedEquationSystem* mes) {
//check should not be needed, but how knows...
if(!m_init) {
if(!isLinked()) {
m_offset = mes->setParameterMap(m_parameterCount, getParameterMap());
m_parameter = m_global;
m_init = true;
}
else {
//it's important that the linked geometry is initialised, as we going to access its parameter map
if(!m_link->isInitialised())
m_link->initMap(mes);
m_offset = m_link->m_offset + m_link_offset;
new(&getParameterMap()) typename Kernel::VectorMap(&m_link->getParameterMap()(m_link_offset), m_parameterCount, typename Kernel::DynStride(1,1));
}
}
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::setClusterMode(bool iscluster, bool isFixed) {
m_isInCluster = iscluster;
m_clusterFixed = isFixed;
if(iscluster) {
//we are in cluster, therefore the parameter map should not point to a solver value but to
//the rotated original value;
new(&m_parameter) typename Kernel::VectorMap(&m_rotated(0), m_parameterCount, DS(1,1));
//the local value is the global one as no transformation was applied yet
m_toplocal = m_global;
m_rotated = m_global;
}
else
new(&m_parameter) typename Kernel::VectorMap(&m_global(0), m_parameterCount, DS(1,1));
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::recalculate(DiffTransform& trans) {
if(!m_isInCluster)
return;
for(int i=0; i!=m_rotations; i++) {
//first rotate the original to the transformed value
m_rotated.block(i*Dim,0,Dim,1) = trans.rotation()*m_toplocal.template segment<Dim>(i*Dim);
//now calculate the gradient vectors and add them to diffparam
for(int j=0; j<Dim; j++)
m_diffparam.block(i*Dim,j,Dim,1) = trans.differential().block(0,j*3,Dim,Dim) * m_toplocal.template segment<Dim>(i*Dim);
}
//after rotating the needed parameters we translate the stuff that needs to be moved
for(int i=0; i!=m_translations; i++) {
m_rotated.block(i*Dim,0,Dim,1) += trans.translation().vector();
m_rotated.block(i*Dim,0,Dim,1) *= trans.scaling().factor();
//calculate the gradient vectors and add them to diffparam
m_diffparam.block(i*Dim,Dim,Dim,Dim).setIdentity();
}
#ifdef USE_LOGGING
if(!boost::math::isnormal(m_rotated.norm()) || !boost::math::isnormal(m_diffparam.norm())) {
BOOST_LOG_SEV(log, error) << "Unnormal recalculated value detected: "<<m_rotated.transpose()<<std::endl
<< "or unnormal recalculated diff detected: "<<std::endl<<m_diffparam<<std::endl
<<" with Transform: "<<std::endl<<trans;
}
#endif
};
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::finishCalculation() {
//if fixed nothing needs to be changed
if(m_isInCluster) {
//recalculate(1.); //remove scaling to get right global value
m_global = m_rotated;
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, information) << "Finish cluster calculation";
#endif
}
//TODO:non cluster parameter scaling
else {
m_global = m_parameter;
normalize();
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, information) << "Finish calculation";
#endif
};
m_init = false;
m_isInCluster = false;
recalculated();
};
template< typename Kernel, int Dim, typename TagList>
template<typename VectorType>
void Geometry<Kernel, Dim, TagList>::transform(const Transform& t, VectorType& vec) {
//everything that needs to be translated needs to be fully transformed
for(int i=0; i!=m_translations; i++) {
typename Kernel::Vector3 v = vec.template segment<Dim>(i*Dim);
vec.template segment<Dim>(i*Dim) = t*v;
}
for(int i=m_translations; i!=m_rotations; i++) {
typename Kernel::Vector3 v = vec.template segment<Dim>(i*Dim);
vec.template segment<Dim>(i*Dim) = t.rotate(v);
}
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, manipulation) << "Transformed with cluster: "<<m_isInCluster
<< ", init: "<<m_init<<" into: "<< vec.transpose();
#endif
}
template< typename Kernel, int Dim, typename TagList>
void Geometry<Kernel, Dim, TagList>::scale(Scalar value) {
for(int i=0; i!=m_translations; i++)
m_parameter.template segment<Dim>(i*Dim) *= 1./value;
};
}
}
#endif // GCM_GEOMETRY_H

View File

@@ -1,524 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_KERNEL_IMP_H
#define DCM_KERNEL_IMP_H
#include "../kernel.hpp"
#include <boost/math/special_functions.hpp>
#include <Eigen/QR>
namespace dcm {
template<typename Kernel>
Dogleg<Kernel>::Dogleg(Kernel* k) : m_kernel(k), tolg(1e-40), tolx(1e-20) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Dogleg"));
#endif
};
template<typename Kernel>
Dogleg<Kernel>::Dogleg() : tolg(1e-6), tolx(1e-3) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Dogleg"));
#endif
};
template<typename Kernel>
void Dogleg<Kernel>::setKernel(Kernel* k) {
m_kernel = k;
};
template<typename Kernel>
template <typename Derived, typename Derived2, typename Derived3, typename Derived4>
void Dogleg<Kernel>::calculateStep(const Eigen::MatrixBase<Derived>& g, const Eigen::MatrixBase<Derived3>& jacobi,
const Eigen::MatrixBase<Derived4>& residual, Eigen::MatrixBase<Derived2>& h_dl,
const double delta) {
// get the steepest descent stepsize and direction
const double alpha(g.squaredNorm()/(jacobi*g).squaredNorm());
const typename Kernel::Vector h_sd = -g;
// get the gauss-newton step
const typename Kernel::Vector h_gn = jacobi.fullPivLu().solve(-residual);
const double eigen_error = (jacobi*h_gn + residual).norm();
#ifdef USE_LOGGING
if(!boost::math::isfinite(h_gn.norm())) {
BOOST_LOG_SEV(log, error) << "Unnormal gauss-newton detected: "<<h_gn.norm();
}
if(!boost::math::isfinite(h_sd.norm())) {
BOOST_LOG_SEV(log, error) << "Unnormal steepest descent detected: "<<h_sd.norm();
}
if(!boost::math::isfinite(alpha)) {
BOOST_LOG_SEV(log, error) << "Unnormal alpha detected: "<<alpha;
}
#endif
// compute the dogleg step
if(h_gn.norm() <= delta) {
h_dl = h_gn;
}
else if((alpha*h_sd).norm() >= delta) {
//h_dl = alpha*h_sd;
h_dl = (delta/(h_sd.norm()))*h_sd;
#ifdef USE_LOGGING
if(!boost::math::isfinite(h_dl.norm())) {
BOOST_LOG_SEV(log, error) << "Unnormal dogleg descent detected: "<<h_dl.norm();
}
#endif
}
else {
//compute beta
number_type beta = 0;
typename Kernel::Vector a = alpha*h_sd;
typename Kernel::Vector b = h_gn;
number_type c = a.transpose()*(b-a);
number_type bas = (b-a).squaredNorm(), as = a.squaredNorm();
if(c<0) {
beta = -c+std::sqrt(std::pow(c,2)+bas*(std::pow(delta,2)-as));
beta /= bas;
}
else {
beta = std::pow(delta,2)-as;
beta /= c+std::sqrt(std::pow(c,2) + bas*(std::pow(delta,2)-as));
};
// and update h_dl and dL with beta
h_dl = alpha*h_sd + beta*(b-a);
#ifdef USE_LOGGING
if(!boost::math::isfinite(c)) {
BOOST_LOG_SEV(log, error) << "Unnormal dogleg c detected: "<<c;
}
if(!boost::math::isfinite(bas)) {
BOOST_LOG_SEV(log, error) << "Unnormal dogleg bas detected: "<<bas;
}
if(!boost::math::isfinite(beta)) {
BOOST_LOG_SEV(log, error) << "Unnormal dogleg beta detected: "<<beta;
}
#endif
}
};
template<typename Kernel>
int Dogleg<Kernel>::solve(typename Kernel::MappedEquationSystem& sys) {
nothing n;
return solve(sys, n);
};
template<typename Kernel>
template<typename Functor>
int Dogleg<Kernel>::solve(typename Kernel::MappedEquationSystem& sys, Functor& rescale) {
clock_t start = clock();
if(!sys.isValid())
throw solving_error() << boost::errinfo_errno(5) << error_message("invalid equation system");
F_old.resize(sys.equationCount());
g.resize(sys.equationCount());
J_old.resize(sys.equationCount(), sys.parameterCount());
sys.recalculate();
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving) << "initial jacobi: "<<std::endl<<sys.Jacobi<<std::endl
<< "residual: "<<sys.Residual.transpose()<<std::endl
<< "maximal differential: "<<sys.Jacobi.template lpNorm<Eigen::Infinity>();
#endif
sys.removeLocalGradientZeros();
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving) << "LGZ jacobi: "<<std::endl<<sys.Jacobi<<std::endl
<< "maximal differential: "<<sys.Jacobi.template lpNorm<Eigen::Infinity>();
#endif
err = sys.Residual.norm();
F_old = sys.Residual;
J_old = sys.Jacobi;
g = sys.Jacobi.transpose()*(sys.Residual);
// get the infinity norm fx_inf and g_inf
g_inf = g.template lpNorm<E::Infinity>();
fx_inf = sys.Residual.template lpNorm<E::Infinity>();
delta=5;
nu=2.;
iter=0;
stop=0;
reduce=0;
unused=0;
counter=0;
int maxIterNumber = m_kernel->template getProperty<iterations>();
number_type pr = m_kernel->template getProperty<precision>()*sys.Scaling;
number_type diverging_lim = 1e6*err + 1e12;
do {
// check if finished
if(fx_inf <= pr) // Success
stop = 1;
else if(g_inf <= tolg*pr)
throw solving_error() << boost::errinfo_errno(2) << error_message("g infinity norm smaller below limit");
else if(delta <= tolx*pr)
throw solving_error() << boost::errinfo_errno(3) << error_message("step size below limit");
else if(iter >= maxIterNumber)
throw solving_error() << boost::errinfo_errno(4) << error_message("maximal iterations reached");
else if(!boost::math::isfinite(err))
throw solving_error() << boost::errinfo_errno(5) << error_message("error is inf or nan");
else if(err > diverging_lim)
throw solving_error() << boost::errinfo_errno(6) << error_message("error diverged");
// see if we are already finished
if(stop)
break;
number_type err_new;
number_type dF=0, dL=0;
number_type rho;
//get the update step
calculateStep(g, sys.Jacobi, sys.Residual, h_dl, delta);
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, iteration) << "Step in iter "<<iter<<std::endl
<< "Step: "<<h_dl.transpose()<<std::endl
<< "Jacobi: "<<sys.Jacobi<<std::endl
<< "Residual: "<<sys.Residual.transpose();
#endif
// calculate the linear model
dL = sys.Residual.norm() - (sys.Residual + sys.Jacobi*h_dl).norm();
// get the new values
sys.Parameter += h_dl;
sys.recalculate();
#ifdef USE_LOGGING
if(!boost::math::isfinite(sys.Residual.norm())) {
BOOST_LOG_SEV(log, error) << "Unnormal residual detected: "<<sys.Residual.norm();
}
if(!boost::math::isfinite(sys.Jacobi.sum())) {
BOOST_LOG_SEV(log, error) << "Unnormal jacobi detected: "<<sys.Jacobi.sum();
}
#endif
//calculate the translation update ratio
err_new = sys.Residual.norm();
dF = err - err_new;
rho = dF/dL;
if(dF<=0 || dL<=0)
rho = -1;
// update delta
if(rho>0.85) {
delta = std::max(delta,2*h_dl.norm());
nu = 2;
}
else if(rho < 0.25) {
delta = delta/nu;
nu = 2*nu;
}
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, iteration)<<"Result of step dF: "<<dF<<", dL: "<<dL<<std::endl
<< "New Residual: "<< sys.Residual.transpose()<<std::endl;
#endif
if(dF > 0 && dL > 0) {
//see if we got too high differentials
if(sys.Jacobi.template lpNorm<Eigen::Infinity>() > 2) {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, iteration)<< "High differential detected: "<<sys.Jacobi.template lpNorm<Eigen::Infinity>()<<" in iteration: "<<iter;
#endif
rescale();
sys.recalculate();
}
//it can also happen that the differentials get too small, however, we can't check for that
else if(iter>1 && (counter>50)) {
rescale();
sys.recalculate();
counter = 0;
}
F_old = sys.Residual;
J_old = sys.Jacobi;
err = sys.Residual.norm();
g = sys.Jacobi.transpose()*(sys.Residual);
// get infinity norms
g_inf = g.template lpNorm<E::Infinity>();
fx_inf = sys.Residual.template lpNorm<E::Infinity>();
}
else {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, iteration)<< "Reject step in iter "<<iter<<", dF: "<<dF<<", dL: "<<dL;
#endif
sys.Residual = F_old;
sys.Jacobi = J_old;
sys.Parameter -= h_dl;
unused++;
}
iter++;
counter++;
}
while(!stop);
clock_t end = clock();
time = (double(end-start) * 1000.) / double(CLOCKS_PER_SEC);
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<<"Done solving: "<<err<<", iter: "<<iter<<", unused: "<<unused<<", reason:"<< stop;
BOOST_LOG_SEV(log, solving)<< "final jacobi: "<<std::endl<<sys.Jacobi
<< "residual: "<<sys.Residual.transpose()<<std::endl
<< "maximal differential: "<<sys.Jacobi.template lpNorm<Eigen::Infinity>();
#endif
return stop;
}
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::MappedEquationSystem::parameterCount() {
return m_params;
};
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::MappedEquationSystem::equationCount() {
return m_eqns;
};
template<typename Scalar, template<class> class Nonlinear>
AccessType Kernel<Scalar, Nonlinear>::MappedEquationSystem::access() {
return m_access;
};
template<typename Scalar, template<class> class Nonlinear>
Kernel<Scalar, Nonlinear>::MappedEquationSystem::MappedEquationSystem(int params, int equations)
: m_access(general), m_jacobi(equations, params),
m_parameter(params), m_residual(equations),
m_params(params), m_eqns(equations), Scaling(1.),
Jacobi(&m_jacobi(0,0),equations,params,DynStride(equations,1)),
Parameter(&m_parameter(0),params,DynStride(1,1)),
Residual(&m_residual(0),equations,DynStride(1,1)) {
m_param_rot_offset = 0;
m_param_trans_offset = params;
m_eqn_rot_offset = 0;
m_eqn_trans_offset = equations;
m_jacobi.setZero(); //important as some places are never written
};
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::MappedEquationSystem::setParameterMap(int number, VectorMap& map, AccessType t) {
if(t == rotation) {
new(&map) VectorMap(&m_parameter(m_param_rot_offset), number, DynStride(1,1));
m_param_rot_offset += number;
return m_param_rot_offset-number;
}
else {
m_param_trans_offset -= number;
new(&map) VectorMap(&m_parameter(m_param_trans_offset), number, DynStride(1,1));
return m_param_trans_offset;
}
};
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::MappedEquationSystem::setParameterMap(Vector3Map& map, AccessType t) {
if(t == rotation) {
new(&map) Vector3Map(&m_parameter(m_param_rot_offset));
m_param_rot_offset += 3;
return m_param_rot_offset-3;
}
else {
m_param_trans_offset -= 3;
new(&map) Vector3Map(&m_parameter(m_param_trans_offset));
return m_param_trans_offset;
}
};
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::MappedEquationSystem::setResidualMap(VectorMap& map, AccessType t) {
if(t == rotation) {
new(&map) VectorMap(&m_residual(m_eqn_rot_offset), 1, DynStride(1,1));
return m_eqn_rot_offset++;
}
else {
new(&map) VectorMap(&m_residual(--m_eqn_trans_offset), 1, DynStride(1,1));
return m_eqn_trans_offset;
}
};
template<typename Scalar, template<class> class Nonlinear>
void Kernel<Scalar, Nonlinear>::MappedEquationSystem::setJacobiMap(int eqn, int offset, int number, CVectorMap& map) {
new(&map) CVectorMap(&m_jacobi(eqn, offset), number, DynStride(0,m_eqns));
};
template<typename Scalar, template<class> class Nonlinear>
void Kernel<Scalar, Nonlinear>::MappedEquationSystem::setJacobiMap(int eqn, int offset, int number, VectorMap& map) {
new(&map) VectorMap(&m_jacobi(eqn, offset), number, DynStride(0,m_eqns));
};
template<typename Scalar, template<class> class Nonlinear>
bool Kernel<Scalar, Nonlinear>::MappedEquationSystem::isValid() {
if(!m_params || !m_eqns)
return false;
return true;
};
template<typename Scalar, template<class> class Nonlinear>
void Kernel<Scalar, Nonlinear>::MappedEquationSystem::setAccess(AccessType t) {
if(t==complete) {
new(&Jacobi) MatrixMap(&m_jacobi(0,0),m_eqns,m_params,DynStride(m_eqns,1));
new(&Parameter) VectorMap(&m_parameter(0),m_params,DynStride(1,1));
new(&Residual) VectorMap(&m_residual(0), m_eqns, DynStride(1,1));
}
else if(t==rotation) {
int num = m_param_trans_offset;
new(&Jacobi) MatrixMap(&m_jacobi(0,0),m_eqn_trans_offset,num,DynStride(m_eqns,1));
new(&Parameter) VectorMap(&m_parameter(0),num,DynStride(1,1));
new(&Residual) VectorMap(&m_residual(0), m_eqn_trans_offset, DynStride(1,1));
}
else if(t==general) {
int num = m_params - m_param_trans_offset;
int eq_num = m_eqns - m_eqn_trans_offset;
new(&Jacobi) MatrixMap(&m_jacobi(m_eqn_trans_offset,m_param_trans_offset),eq_num,num,DynStride(m_eqns,1));
new(&Parameter) VectorMap(&m_parameter(m_param_trans_offset),num,DynStride(1,1));
new(&Residual) VectorMap(&m_residual(m_eqn_trans_offset), eq_num, DynStride(1,1));
}
m_access = t;
};
template<typename Scalar, template<class> class Nonlinear>
bool Kernel<Scalar, Nonlinear>::MappedEquationSystem::hasAccessType(AccessType t) {
if(t==rotation)
return (m_param_rot_offset>0 && m_eqn_rot_offset>0);
else if(t==general)
return (m_param_trans_offset<m_params && m_eqn_trans_offset<m_eqns);
else
return (m_params>0 && m_eqns>0);
};
template<typename Scalar, template<class> class Nonlinear>
Kernel<Scalar, Nonlinear>::Kernel() {
//init the solver
m_solver.setKernel(this);
}
template<typename Scalar, template<class> class Nonlinear>
SolverInfo Kernel<Scalar, Nonlinear>::getSolverInfo() {
SolverInfo info;
info.iterations = m_solver.iter;
info.error = m_solver.err;
info.time = m_solver.time;
return info;
}
//static comparison versions
template<typename Scalar, template<class> class Nonlinear>
template <typename DerivedA,typename DerivedB>
bool Kernel<Scalar, Nonlinear>::isSame(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2, number_type precision) {
return ((p1-p2).squaredNorm() < precision);
}
template<typename Scalar, template<class> class Nonlinear>
bool Kernel<Scalar, Nonlinear>::isSame(number_type t1, number_type t2, number_type precision) {
return (std::abs(t1-t2) < precision);
}
template<typename Scalar, template<class> class Nonlinear>
template <typename DerivedA,typename DerivedB>
bool Kernel<Scalar, Nonlinear>::isOpposite(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2, number_type precision) {
return ((p1+p2).squaredNorm() < precision);
}
template<typename Scalar, template<class> class Nonlinear>
template <typename DerivedA,typename DerivedB>
bool Kernel<Scalar, Nonlinear>::isSame(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2) {
return ((p1-p2).squaredNorm() < getProperty<precision>());
}
template<typename Scalar, template<class> class Nonlinear>
bool Kernel<Scalar, Nonlinear>::isSame(number_type t1, number_type t2) {
return (std::abs(t1-t2) < getProperty<precision>());
}
template<typename Scalar, template<class> class Nonlinear>
template <typename DerivedA,typename DerivedB>
bool Kernel<Scalar, Nonlinear>::isOpposite(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2) {
return ((p1+p2).squaredNorm() < getProperty<precision>());
}
template<typename Scalar, template<class> class Nonlinear>
int Kernel<Scalar, Nonlinear>::solve(MappedEquationSystem& mes) {
nothing n;
return m_solver.solve(mes, n);
};
template<typename Scalar, template<class> class Nonlinear>
template<typename Functor>
int Kernel<Scalar, Nonlinear>::solve(MappedEquationSystem& mes, Functor& f) {
return m_solver.solve(mes, f);
};
}
#endif //GCM_KERNEL_H

View File

@@ -1,115 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_OBJECT_IMP_H
#define GCM_OBJECT_IMP_H
#include <iostream>
#include <map>
#include <boost/mpl/at.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/key_type.hpp>
#include <boost/mpl/value_type.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "../property.hpp"
#define EMIT_CALL_DEC(z, n, data) \
template<typename SigMap> \
template < \
typename S \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg) \
> \
void SignalOwner<SigMap>::emitSignal( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
{ \
if(m_emit_signals) {\
typedef typename mpl::find<sig_name, S>::type iterator; \
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance; \
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type; \
map_type& map = fusion::at<distance>(m_signals); \
for (typename map_type::iterator it=map.begin(); it != map.end(); it++) \
(it->second)(BOOST_PP_ENUM(n, EMIT_ARGUMENTS, arg)); \
}\
};
namespace dcm {
template<typename Sys, typename Derived, typename Sig>
Object<Sys, Derived, Sig>::Object(Sys& system) : m_system(&system) {};
template<typename Sys, typename Derived, typename Sig>
std::shared_ptr<Derived> Object<Sys, Derived, Sig>::clone(Sys& newSys)
{
std::shared_ptr<Derived> np = std::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
return np;
};
template<typename SigMap>
SignalOwner<SigMap>::SignalOwner() : m_emit_signals(true), m_signal_count(0) {};
template<typename SigMap>
template<typename S>
Connection SignalOwner<SigMap>::connectSignal(typename mpl::at<SigMap, S>::type function)
{
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type;
map_type& map = fusion::at<distance>(m_signals);
map[++m_signal_count] = function;
return m_signal_count;
};
template<typename SigMap>
template<typename S>
void SignalOwner<SigMap>::disconnectSignal(Connection c)
{
typedef typename mpl::find<sig_name, S>::type iterator;
typedef typename mpl::distance<typename mpl::begin<sig_name>::type, iterator>::type distance;
typedef typename fusion::result_of::value_at<Signals, distance>::type map_type;
map_type& map = fusion::at<distance>(m_signals);
map.erase(c);
};
template<typename SigMap>
void SignalOwner<SigMap>::enableSignals(bool onoff)
{
m_emit_signals = onoff;
};
BOOST_PP_REPEAT(5, EMIT_CALL_DEC, ~)
}
#endif //GCM_OBJECT_H

View File

@@ -1,177 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_SYSTEM_IMP_H
#define DCM_SYSTEM_IMP_H
#ifdef DCM_EXTERNAL_CORE
#include "kernel_imp.hpp"
#include "transformation_imp.hpp"
#include "clustergraph_imp.hpp"
#include "equations_imp.hpp"
#endif
#include "../system.hpp"
#include <boost/fusion/include/for_each.hpp>
namespace dcm {
struct clearer {
template<typename T>
void operator()(T& vector) const {
vector.clear();
};
};
template<typename System>
struct cloner {
System& newSys;
cloner(System& ns) : newSys(ns) {};
template<typename T>
struct test : mpl::and_<details::is_shared_ptr<T>,
mpl::not_<boost::is_same<T, std::shared_ptr<typename System::Cluster> > > > {};
template<typename T>
typename boost::enable_if< test<T>, void>::type operator()(T& p) const {
p = p->clone(newSys);
newSys.push_back(p);
};
template<typename T>
typename boost::enable_if< mpl::not_<test<T> >, void>::type operator()(const T& p) const {};
};
template< typename KernelType, typename T1, typename T2, typename T3 >
System<KernelType, T1, T2, T3>::System() : m_cluster(new Cluster),
m_storage(new Storage), m_options(new OptionOwner)
#ifdef USE_LOGGING
, sink(init_log())
#endif
{
Type1::system_init(*this);
Type2::system_init(*this);
Type3::system_init(*this);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
System<KernelType, T1, T2, T3>::~System() {
#ifdef USE_LOGGING
stop_log(sink);
#endif
};
template< typename KernelType, typename T1, typename T2, typename T3 >
void System<KernelType, T1, T2, T3>::clear() {
m_cluster->clearClusters();
m_cluster->clear();
fusion::for_each(*m_storage, clearer());
};
template< typename KernelType, typename T1, typename T2, typename T3 >
SolverInfo System<KernelType, T1, T2, T3>::solve() {
clock_t start = clock();
m_scheduler.execute(*this);
clock_t end = clock();
SolverInfo info = m_kernel.getSolverInfo();
info.time = (double(end-start)* 1000.) / double(CLOCKS_PER_SEC);
//signal our successful solving
BaseType::template emitSignal<solved>(this);
return info;
};
template< typename KernelType, typename T1, typename T2, typename T3 >
std::shared_ptr<System<KernelType, T1, T2, T3> > System<KernelType, T1, T2, T3>::createSubsystem() {
std::shared_ptr<System> s = std::shared_ptr<System>(new System());
s->m_cluster = m_cluster->createCluster().first;
s->m_storage = m_storage;
s->m_cluster->template setProperty<dcm::type_prop>(details::subcluster);
s->m_options = m_options;
#ifdef USE_LOGGING
stop_log(s->sink);
#endif
//inform modules that we have a subsystem now
Inheriter1::system_sub(s);
Inheriter2::system_sub(s);
Inheriter3::system_sub(s);
m_subsystems.push_back(s);
return s;
};
template< typename KernelType, typename T1, typename T2, typename T3 >
typename std::vector<std::shared_ptr<System<KernelType, T1, T2, T3> > >::iterator System<KernelType, T1, T2, T3>::beginSubsystems() {
return m_subsystems.begin();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
typename std::vector<std::shared_ptr<System<KernelType, T1, T2, T3> > >::iterator System<KernelType, T1, T2, T3>::endSubsystems() {
return m_subsystems.end();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
KernelType& System<KernelType, T1, T2, T3>::kernel() {
return m_kernel;
};
template< typename KernelType, typename T1, typename T2, typename T3 >
void System<KernelType, T1, T2, T3>::copyInto(System<KernelType, T1, T2, T3>& into) const {
//copy the clustergraph and clone all objects while at it. They are also pushed to the storage
cloner<System> cl(into);
m_cluster->copyInto(into.m_cluster, cl);
//notify all modules that they are copied
Type1::system_copy(*this, into);
Type2::system_copy(*this, into);
Type3::system_copy(*this, into);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
System<KernelType, T1, T2, T3>* System<KernelType, T1, T2, T3>::clone() const {
System* ns = new System();
this->copyInto(*ns);
return ns;
};
}
#endif //GCM_SYSTEM_H

View File

@@ -1,323 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_TRANSFORMATION_IMP_H
#define DCM_TRANSFORMATION_IMP_H
#include "../transformation.hpp"
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <boost/mpl/if.hpp>
namespace dcm {
namespace detail {
template<typename Scalar, int Dim>
Transform<Scalar, Dim>::Transform() : m_rotation(Rotation::Identity()),
m_translation(Translation::Identity()),
m_scale(Scaling(1.)) { };
template<typename Scalar, int Dim>
Transform<Scalar, Dim>::Transform(const Rotation& r) : m_rotation(r),
m_translation(Translation::Identity()),
m_scale(Scaling(1.)) {
m_rotation.normalize();
};
template<typename Scalar, int Dim>
Transform<Scalar, Dim>::Transform(const Rotation& r, const Translation& t) : m_rotation(r),
m_translation(t),
m_scale(Scaling(1.)) {
m_rotation.normalize();
};
template<typename Scalar, int Dim>
Transform<Scalar, Dim>::Transform(const Rotation& r, const Translation& t, const Scaling& s) : m_rotation(r),
m_translation(t),
m_scale(s) {
m_rotation.normalize();
};
template<typename Scalar, int Dim>
const typename Transform<Scalar, Dim>::Rotation& Transform<Scalar, Dim>::rotation() const {
return m_rotation;
}
template<typename Scalar, int Dim>
template<typename Derived>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::setRotation(const Eigen::RotationBase<Derived,Dim>& rotation) {
m_rotation = rotation.derived().normalized();
return *this;
}
template<typename Scalar, int Dim>
template<typename Derived>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::rotate(const Eigen::RotationBase<Derived,Dim>& rotation) {
m_rotation = rotation.derived().normalized()*m_rotation;
return *this;
}
template<typename Scalar, int Dim>
const typename Transform<Scalar, Dim>::Translation& Transform<Scalar, Dim>::translation() const {
return m_translation;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::setTranslation(const Translation& translation) {
m_translation = translation;
return *this;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::translate(const Translation& translation) {
m_translation = m_translation*translation;
return *this;
}
template<typename Scalar, int Dim>
const typename Transform<Scalar, Dim>::Scaling& Transform<Scalar, Dim>::scaling() const {
return m_scale;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::scale(const Scalar& scaling) {
m_scale *= Scaling(scaling);
return *this;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::setScale(const Scaling& scaling) {
m_scale.factor() = scaling.factor();
return *this;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::scale(const Scaling& scaling) {
m_scale.factor() *= scaling.factor();
return *this;
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::invert() {
m_rotation = m_rotation.inverse();
m_translation.vector() = (m_rotation*m_translation.vector()) * (-m_scale.factor());
m_scale = Scaling(1./m_scale.factor());
return *this;
};
template<typename Scalar, int Dim>
Transform<Scalar, Dim> Transform<Scalar, Dim>::inverse() {
Transform res(*this);
res.invert();
return res;
};
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator=(const Translation& t) {
m_translation = t;
m_rotation = Rotation::Identity();
m_scale = Scaling(1.);
return *this;
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim> Transform<Scalar, Dim>::operator*(const Translation& t) const {
Transform res = *this;
res.translate(t);
return res;
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator*=(const Translation& t) {
return translate(t);
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator=(const Scaling& s) {
m_scale = s;
m_translation = Translation::Identity();
m_rotation = Rotation::Identity();
return *this;
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim> Transform<Scalar, Dim>::operator*(const Scaling& s) const {
Transform res = *this;
res.scale(s);
return res;
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator*=(const Scaling& s) {
return scale(s);
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator=(const Eigen::RotationBase<Derived,Dim>& r) {
m_rotation = r.derived();
m_rotation.normalize();
m_translation = Translation::Identity();
m_scale = Scaling(1);
return *this;
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Transform<Scalar, Dim> Transform<Scalar, Dim>::operator*(const Eigen::RotationBase<Derived,Dim>& r) const {
Transform res = *this;
res.rotate(r.derived());
return res;
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator*=(const Eigen::RotationBase<Derived,Dim>& r) {
return rotate(r.derived());
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim> Transform<Scalar, Dim>::operator* (const Transform& other) const {
Transform res(*this);
res*= other;
return res;
}
template<typename Scalar, int Dim>
inline Transform<Scalar, Dim>& Transform<Scalar, Dim>::operator*= (const Transform& other) {
rotate(other.rotation());
other.rotate(m_translation.vector());
m_translation.vector() += other.translation().vector()/m_scale.factor();
m_scale.factor() *= other.scaling().factor();
return *this;
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Derived& Transform<Scalar, Dim>::rotate(Eigen::MatrixBase<Derived>& vec) const {
vec = m_rotation*vec;
return vec.derived();
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Derived& Transform<Scalar, Dim>::translate(Eigen::MatrixBase<Derived>& vec) const {
vec = m_translation*vec;
return vec.derived();
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Derived& Transform<Scalar, Dim>::scale(Eigen::MatrixBase<Derived>& vec) const {
vec*=m_scale.factor();
return vec.derived();
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Derived& Transform<Scalar, Dim>::transform(Eigen::MatrixBase<Derived>& vec) const {
vec = (m_rotation*vec + m_translation.vector())*m_scale.factor();
return vec.derived();
}
template<typename Scalar, int Dim>
template<typename Derived>
inline Derived Transform<Scalar, Dim>::operator*(const Eigen::MatrixBase<Derived>& vec) const {
return (m_rotation*vec + m_translation.vector())*m_scale.factor();
}
template<typename Scalar, int Dim>
template<typename Derived>
inline void Transform<Scalar, Dim>::operator()(Eigen::MatrixBase<Derived>& vec) const {
transform(vec);
}
template<typename Scalar, int Dim>
bool Transform<Scalar, Dim>::isApprox(const Transform& other, Scalar prec) const {
return m_rotation.isApprox(other.rotation(), prec)
&& ((m_translation.vector()- other.translation().vector()).norm() < prec)
&& (std::abs(m_scale.factor()-other.scaling().factor()) < prec);
};
template<typename Scalar, int Dim>
void Transform<Scalar, Dim>::setIdentity() {
m_rotation.setIdentity();
m_translation = Translation::Identity();
m_scale = Scaling(1.);
}
template<typename Scalar, int Dim>
const Transform<Scalar, Dim> Transform<Scalar, Dim>::Identity() {
return Transform(Rotation::Identity(), Translation::Identity(), Scaling(1));
}
template<typename Scalar, int Dim>
Transform<Scalar, Dim>& Transform<Scalar, Dim>::normalize() {
m_rotation.normalize();
return *this;
}
template<typename Scalar, int Dim>
DiffTransform<Scalar, Dim>::DiffTransform(Transform<Scalar, Dim>& trans)
: Transform<Scalar, Dim>(trans.rotation(), trans.translation(), trans.scaling()) {
m_diffMatrix.setZero();
};
template<typename Scalar, int Dim>
const typename DiffTransform<Scalar, Dim>::DiffMatrix&
DiffTransform<Scalar, Dim>::differential() {
return m_diffMatrix;
};
template<typename Scalar, int Dim>
inline Scalar&
DiffTransform<Scalar, Dim>::operator()(int f, int s) {
return m_diffMatrix(f,s);
};
template<typename Scalar, int Dim>
inline Scalar&
DiffTransform<Scalar, Dim>::at(int f, int s) {
return m_diffMatrix(f,s);
};
/*When you overload a binary operator as a member function of a class the overload is used
* when the first operand is of the class type.For stream operators, the first operand
* is the stream and not (usually) the custom class.
*/
template<typename charT, typename traits, typename Kernel, int Dim>
std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& os, const dcm::detail::Transform<Kernel, Dim>& t) {
os << "Rotation: " << t.rotation().coeffs().transpose() << std::endl
<< "Translation: " << t.translation().vector().transpose() <<std::endl
<< "Scale: " << t.scaling().factor();
return os;
}
template<typename charT, typename traits,typename Kernel, int Dim>
std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& os, dcm::detail::DiffTransform<Kernel, Dim>& t) {
os << "Rotation: " << t.rotation().coeffs().transpose() << std::endl
<< "Translation: " << t.translation().vector().transpose() <<std::endl
<< "Scale: " << t.scaling().factor() << std::endl
<< "Differential:" << std::endl<<t.differential();
return os;
}
}//detail
}//DCM
#endif //DCM_TRANSFORMATION

View File

@@ -1,240 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_KERNEL_H
#define DCM_KERNEL_H
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Geometry>
#include "transformation.hpp"
#include "logging.hpp"
#include "defines.hpp"
#include "property.hpp"
namespace E = Eigen;
namespace mpl= boost::mpl;
namespace dcm {
struct nothing {
void operator()() {};
};
//information about solving
struct SolverInfo {
int iterations;
double error;
double time;
};
//the parameter types
enum AccessType {
general, //every non-rotation parameter, therefore every translation and non transformed parameter
rotation, //all rotation parameters
complete //all parameter
};
//solver settings
struct precision {
typedef double type;
typedef setting_property kind;
struct default_value {
double operator()() {
return 1e-6;
};
};
};
struct iterations {
typedef int type;
typedef setting_property kind;
struct default_value {
int operator()() {
return int(5e3);
};
};
};
//and the solver itself
template<typename Kernel>
struct Dogleg {
#ifdef USE_LOGGING
dcm_logger log;
#endif
typedef typename Kernel::number_type number_type;
number_type tolg, tolx, delta, nu, g_inf, fx_inf, err, time;
Kernel* m_kernel;
int iter, stop, reduce, unused, counter;
typename Kernel::Vector h_dl, F_old, g;
typename Kernel::Matrix J_old;
Dogleg(Kernel* k);
Dogleg();
void setKernel(Kernel* k);
template <typename Derived, typename Derived2, typename Derived3, typename Derived4>
void calculateStep(const Eigen::MatrixBase<Derived>& g, const Eigen::MatrixBase<Derived3>& jacobi,
const Eigen::MatrixBase<Derived4>& residual, Eigen::MatrixBase<Derived2>& h_dl,
const double delta);
int solve(typename Kernel::MappedEquationSystem& sys);
template<typename Functor>
int solve(typename Kernel::MappedEquationSystem& sys, Functor& rescale);
};
template<typename Scalar, template<class> class Nonlinear = Dogleg>
struct Kernel : public PropertyOwner< mpl::vector2<precision, iterations> > {
//basics
typedef Scalar number_type;
//linear algebra types 2D
typedef E::Matrix<Scalar, 2, 1> Vector2;
//Linear algebra types 3D
typedef E::Matrix<Scalar, 3, 1> Vector3;
typedef E::Matrix<Scalar, 1, 3> CVector3;
typedef E::Matrix<Scalar, 3, 3> Matrix3;
typedef E::Matrix<Scalar, E::Dynamic, 1> Vector;
typedef E::Matrix<Scalar, 1, E::Dynamic> CVector;
typedef E::Matrix<Scalar, E::Dynamic, E::Dynamic> Matrix;
//mapped types
typedef E::Stride<E::Dynamic, E::Dynamic> DynStride;
typedef E::Map< Vector3 > Vector3Map;
typedef E::Map< CVector3> CVector3Map;
typedef E::Map< Matrix3 > Matrix3Map;
typedef E::Map< Vector, 0, DynStride > VectorMap;
typedef E::Map< CVector, 0, DynStride > CVectorMap;
typedef E::Map< Matrix, 0, DynStride > MatrixMap;
//Special types
typedef E::Quaternion<Scalar> Quaternion;
typedef E::Matrix<Scalar, 3, 9> Matrix39;
typedef E::Map< Matrix39 > Matrix39Map;
typedef E::Block<Matrix> MatrixBlock;
typedef detail::Transform<Scalar, 3> Transform3D;
typedef detail::DiffTransform<Scalar, 3> DiffTransform3D;
typedef detail::Transform<Scalar, 2> Transform2D;
typedef detail::DiffTransform<Scalar, 2> DiffTransform2D;
typedef Nonlinear< Kernel<Scalar, Nonlinear> > NonlinearSolver;
template<int Dim>
struct transform_type {
typedef typename boost::mpl::if_c<Dim==2, Transform2D, Transform3D>::type type;
typedef typename boost::mpl::if_c<Dim==2, DiffTransform2D, DiffTransform3D>::type diff_type;
};
template<int Dim>
struct vector_type {
typedef E::Matrix<Scalar, Dim, 1> type;
};
struct MappedEquationSystem {
//protected:
Matrix m_jacobi;
Vector m_parameter, m_residual;
AccessType m_access; //which parameters/equation shall be calculated?
int m_params, m_eqns; //total amount
int m_param_rot_offset, m_param_trans_offset, m_eqn_rot_offset, m_eqn_trans_offset; //current positions while creation
public:
MatrixMap Jacobi;
VectorMap Parameter;
VectorMap Residual;
number_type Scaling;
int parameterCount();
int equationCount();
AccessType access();
MappedEquationSystem(int params, int equations);
int setParameterMap(int number, VectorMap& map, AccessType t = general);
int setParameterMap(Vector3Map& map, AccessType t = general);
int setResidualMap(VectorMap& map, AccessType t = general);
void setJacobiMap(int eqn, int offset, int number, CVectorMap& map);
void setJacobiMap(int eqn, int offset, int number, VectorMap& map);
bool isValid();
void setAccess(AccessType t);
bool hasAccessType(AccessType t);
virtual void recalculate() = 0;
virtual void removeLocalGradientZeros() = 0;
};
Kernel();
//static comparison versions
template <typename DerivedA,typename DerivedB>
static bool isSame(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2, number_type precision);
static bool isSame(number_type t1, number_type t2, number_type precision);
template <typename DerivedA,typename DerivedB>
static bool isOpposite(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2, number_type precision);
//runtime comparison versions (which use user settings for precision)
template <typename DerivedA,typename DerivedB>
bool isSame(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2);
bool isSame(number_type t1, number_type t2);
template <typename DerivedA,typename DerivedB>
bool isOpposite(const E::MatrixBase<DerivedA>& p1,const E::MatrixBase<DerivedB>& p2);
int solve(MappedEquationSystem& mes);
template<typename Functor>
int solve(MappedEquationSystem& mes, Functor& f);
SolverInfo getSolverInfo();
private:
NonlinearSolver m_solver;
};
}//dcm
#ifndef DCM_EXTERNAL_CORE
#include "imp/kernel_imp.hpp"
#endif
#endif //GCM_KERNEL_H

View File

@@ -1,105 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_LOGGING_H
#define GCM_LOGGING_H
#ifdef USE_LOGGING
#define BOOST_LOG_DYN_LINK
#include <boost/log/core.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/expressions/formatters.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/expressions.hpp>
#include <memory>
namespace logging = boost::log;
namespace sinks = boost::log::sinks;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;
namespace dcm {
enum severity_level {
iteration,
solving,
manipulation,
information,
error
};
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
static int counter = 0;
typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
typedef src::severity_logger< severity_level > dcm_logger;
inline std::shared_ptr< sink_t > init_log() {
//create the filename
std::stringstream str;
str<<"openDCM_"<<counter<<"_%N.log";
counter++;
std::shared_ptr< logging::core > core = logging::core::get();
std::shared_ptr< sinks::text_file_backend > backend =
boost::make_shared< sinks::text_file_backend >(
keywords::file_name = str.str(), //file name pattern
keywords::rotation_size = 10 * 1024 * 1024 //Rotation size is 10MB
);
// Wrap it into the frontend and register in the core.
// The backend requires synchronization in the frontend.
std::shared_ptr< sink_t > sink(new sink_t(backend));
sink->set_formatter(
expr::stream <<"[" << expr::attr<std::string>("Tag") <<"] "
<< expr::if_(expr::has_attr<std::string>("ID")) [
expr::stream << "["<< expr::attr< std::string >("ID")<<"] "]
<< expr::smessage
);
core->add_sink(sink);
return sink;
};
inline void stop_log(std::shared_ptr< sink_t >& sink) {
std::shared_ptr< logging::core > core = logging::core::get();
// Remove the sink from the core, so that no records are passed to it
core->remove_sink(sink);
sink.reset();
};
}; //dcm
#endif //USE_LOGGING
#endif //GCM_LOGGING_H

View File

@@ -1,404 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CORE_MULTIMAP_H
#define DCM_CORE_MULTIMAP_H
#include <Eigen/Dense>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/at_c.hpp>
namespace dcm {
namespace details {
template<typename Derived>
class MultiMap;
}
}
namespace Eigen {
namespace internal {
template<typename PlainObjectType>
struct traits<dcm::details::MultiMap<PlainObjectType> >
: public traits<PlainObjectType> {
typedef traits<PlainObjectType> TraitsBase;
typedef typename PlainObjectType::Index Index;
typedef typename PlainObjectType::Scalar Scalar;
enum {
InnerStrideAtCompileTime = int(PlainObjectType::InnerStrideAtCompileTime),
OuterStrideAtCompileTime = int(PlainObjectType::OuterStrideAtCompileTime),
HasNoInnerStride = InnerStrideAtCompileTime == 1,
HasNoOuterStride = OuterStrideAtCompileTime == 1,
HasNoStride = HasNoInnerStride && HasNoOuterStride,
IsAligned = false,//bool(EIGEN_ALIGN),
IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,
KeepsPacketAccess = bool(HasNoInnerStride)
&& (bool(IsDynamicSize)
|| HasNoOuterStride
|| (OuterStrideAtCompileTime != Dynamic
&& ((static_cast<int>(sizeof(Scalar)) * OuterStrideAtCompileTime) % 16) == 0)),
Flags0 = TraitsBase::Flags & (~NestByRefBit),
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
Flags3 = is_lvalue<PlainObjectType>::value ? int(Flags2) : (int(Flags2) & ~LvalueBit),
Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit)
};
private:
enum { Options }; // Expressions don't have Options
};
} //internal
} //Eigen
namespace dcm {
namespace details {
using namespace Eigen; //needed for macros
namespace fusion = boost::fusion;
template<typename Derived>
class MultiMapBase : public internal::dense_xpr_base<Derived>::type {
public:
typedef typename internal::dense_xpr_base<Derived>::type Base;
enum {
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
SizeAtCompileTime = Base::SizeAtCompileTime
};
typedef typename internal::traits<Derived>::StorageKind StorageKind;
typedef typename internal::traits<Derived>::Index Index;
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename internal::conditional <
bool(internal::is_lvalue<Derived>::value),
Scalar*,
const Scalar* >::type
PointerType;
using Base::derived;
using Base::MaxRowsAtCompileTime;
using Base::MaxColsAtCompileTime;
using Base::MaxSizeAtCompileTime;
using Base::IsVectorAtCompileTime;
using Base::Flags;
using Base::IsRowMajor;
using Base::size;
using Base::coeff;
using Base::coeffRef;
using Base::lazyAssign;
using Base::eval;
// bug 217 - compile error on ICC 11.1
using Base::operator=;
typedef typename Base::CoeffReturnType CoeffReturnType;
typedef Stride<Dynamic, Dynamic> DynStride;
typedef fusion::vector6<PointerType, int, int, int, int, DynStride> MapData;
inline Index rows() const {
return m_rows.value();
}
inline Index cols() const {
return m_cols.value();
}
inline const Scalar* data() const {
assert(false);
return m_data;
}
inline const Scalar& coeff(Index row, Index col) const {
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > row && fusion::at_c<1>(data) <= row
&& (fusion::at_c<2>(data) + fusion::at_c<4>(data)) > col && fusion::at_c<2>(data) <= col)
return fusion::at_c<0>(data)[(col - fusion::at_c<2>(data)) * fusion::at_c<5>(data).outer() + (row - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner()];
};
return default_value;
}
inline const Scalar& coeff(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > index)
return fusion::at_c<0>(data)[(index - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner()];
};
return default_value;
}
inline const Scalar& coeffRef(Index row, Index col) const {
return coeff(row, col);
}
inline const Scalar& coeffRef(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return coeff(index);
}
template<int LoadMode>
inline PacketScalar packet(Index row, Index col) const {
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > row && fusion::at_c<1>(data) <= row
&& (fusion::at_c<2>(data) + fusion::at_c<4>(data)) > col && fusion::at_c<2>(data) <= col)
return internal::ploadt<PacketScalar, LoadMode>
(fusion::at_c<0>(data) + (col - fusion::at_c<2>(data)) * fusion::at_c<5>(data).outer() + (row - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner());
};
return internal::ploadt<PacketScalar, LoadMode>(&default_value);
}
template<int LoadMode>
inline PacketScalar packet(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > index)
return internal::ploadt<PacketScalar, LoadMode>(fusion::at_c<0>(data) + (index - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner());
};
return internal::ploadt<PacketScalar, LoadMode>(&default_value);
}
// constructor for datapointer which resembles the fixed size derived type
// this works only if this is the only mapped data!
inline MultiMapBase(PointerType data)
: default_value(0), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
// constructor for datapointer which resembles the derived dynamic size vector
inline MultiMapBase(PointerType data, Index size)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? 1 : Index(ColsAtCompileTime)) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, 0, 0, size, 1, DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
// constructor for datapointer which resembles the derived dynamic size matrix
// this works only if this matrix is the only mapped data!
inline MultiMapBase(PointerType data, Index rows, Index cols)
: default_value(0), m_rows(rows), m_cols(cols) {
eigen_assert((data == 0)
|| (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//the fixed size derived type. This only works if this is the only data
template<typename Stride>
inline MultiMapBase(PointerType data, const Stride& stride)
: default_value(0), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(stride.outer(), stride.inner())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//a part or all of the derived vector type.
template<typename Stride>
inline MultiMapBase(PointerType data, Index size, const Stride& stride)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime)) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(stride.outer(), stride.inner())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//a part or all of the derived matrix type
template<typename Stride>
inline MultiMapBase(PointerType data, Index rows, Index cols, const Stride& stride)
: default_value(0), m_rows(rows), m_cols(cols) {
eigen_assert((data == 0)
|| (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
//constructor for arbitrary dense matrix types. The matrix must resemble a part or all of the
//derived type.
template<typename DerivedType>
inline MultiMapBase(MatrixBase<DerivedType>& matrix)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? matrix.rows() : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? matrix.cols() : Index(ColsAtCompileTime)) {
m_data.push_back(fusion::make_vector(&matrix(0, 0), 0, 0, matrix.rows(), matrix.cols(), DynStride(matrix.outerStride(), matrix.innerStride())));
checkSanity();
};
//map extensions
//**************
//extend with data vector in derived type form
inline void extend(PointerType data, Index size) {
extend(data, size, DynStride(Base::outerStride(), Base::innerStride()));
};
//extend with data vector in arbitrary form
template<typename Stride>
inline void extend(PointerType data, Index size, const Stride& stride) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, m_rows.value(), 0, size, 1, DynStride(stride.outer(), stride.inner())));
m_rows.setValue(m_rows.value() + size);
checkSanity();
};
//extend with eigen vector
template<typename DerivedType>
inline void extend(MatrixBase<DerivedType>& matrix) {
//this only works for vectors, as we would not know where to add a matrix
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(matrix.cols() == 1);
extend(matrix.derived().data(), matrix.rows(), DynStride(matrix.outerStride(), matrix.innerStride()));
};
//extend with general pointer data
template<typename Stride>
inline void extend(PointerType matrix, Index row, Index col, Index rows, Index cols, const Stride& stride) {
m_data.push_back(fusion::make_vector(matrix, row, col, rows, cols, DynStride(stride.outer(), stride.inner())));
if((row + rows) > m_rows.value())
m_rows.setValue(row + rows);
if((col + cols) > m_cols.value())
m_cols.setValue(col + cols);
checkSanity();
};
//extend with pointer data in derived type form
inline void extend(PointerType matrix, Index row, Index col, Index rows, Index cols) {
extend(matrix.derived().data(), row, col, rows, cols, DynStride(Base::outerStride(), Base::innerStride()));
};
//extend with eigen matrix
template<typename DerivedType>
inline void extend(MatrixBase<DerivedType>& matrix, Index row, Index col) {
extend(matrix.derived().data(), row, col, matrix.rows(), matrix.cols(), DynStride(matrix.outerStride(), matrix.innerStride()));
};
protected:
void checkSanity() const {
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags & PacketAccessBit,
internal::inner_stride_at_compile_time<Derived>::ret == 1),
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags & AlignedBit, (size_t(fusion::at_c<0>(m_data.back())) % 16) == 0)
&& "data is not aligned");
}
std::vector<MapData> m_data;
Scalar default_value;
internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
};
//this indirection is needed so that the map base coeff functions are called
template<typename Derived>
class MultiMap : public MultiMapBase< MultiMap<Derived> > {
public:
typedef MultiMapBase< MultiMap<Derived> > Base;
EIGEN_DENSE_PUBLIC_INTERFACE(MultiMap)
inline Index innerStride() const {
return 1;
}
inline Index outerStride() const {
if(Flags & RowMajorBit)
return Base::m_cols.value();
else // column-major
return Base::m_rows.value();
}
inline MultiMap(typename Base::PointerType matrix) : Base(matrix) {};
inline MultiMap(typename Base::PointerType matrix, typename Base::Index size) : Base(matrix, size) {};
inline MultiMap(typename Base::PointerType matrix,
typename Base::Index row,
typename Base::Index col) : Base(matrix, row, col) {};
template<typename DerivedType>
inline MultiMap(MatrixBase<DerivedType>& matrix) : Base(matrix) {};
};
} // details
} // dcm
#endif // EIGEN_MAPBASE_H

View File

@@ -1,188 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_OBJECT_H
#define GCM_OBJECT_H
#include <iostream>
#include <map>
#include <boost/mpl/at.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/key_type.hpp>
#include <boost/mpl/value_type.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "property.hpp"
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
/* Preprocessor implementation of emit signal. As we need many overloads with different number of
* templated parameters we use boost preprocessor to do the hard repetitive work. The definition and
* implementation are defined first as they need to be known before usage
* */
#define EMIT_ARGUMENTS(z, n, data) \
BOOST_PP_CAT(data, n)
#define EMIT_CALL_DEF(z, n, data) \
template < \
typename S \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg) \
> \
void emitSignal( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
);
namespace dcm {
/** @defgroup Objects Objects
*
* @brief Concept and functionality of the dcm objects
*
*
**/
//few standard signal names
struct remove {};
typedef int Connection;
template<typename SigMap>
struct SignalOwner {
SignalOwner();
/**
* @brief Connects a slot to a specified signal.
*
* Slots are boost::functions which get called when the signal is emitted. Any valid boost::function
* which ressembles the signal types signature can be registered. It is important that the signal type
* was registered to this object on creation by the appropriate template parameter.
*
* @tparam S the signal which should be intercepted
* @param function boost::function which resembles the signal type's signature
* @return void
**/
template<typename S>
Connection connectSignal(typename mpl::at<SigMap, S>::type function);
/**
* @brief Disconnects a slot for a specific signal.
*
* Disconnects a slot so that it doesn't get called at signal emission. It's important to
* disconnect the slot by the same boost:function it was connected with.
*
* @tparam S the signal type of interest
* @param c connection with which the slot was initially connected
* @return void
**/
template<typename S>
void disconnectSignal(Connection c);
/**
* @brief Enable or disable signal emission
*
* If you want to suppress all signals emitted by an object you can do this by calling this function.
* All calls to emitSignal() will be blocked until signals are reenabled by using this function with
* onoff = true. Note that signals are not queued, if emitting is disabled all signals are lost.
*
* @param onoff bool value if signals shall be emitted or if they are disabled
*/
void enableSignals(bool onoff);
//with no vararg templates before c++11 we need preprocessor to create the overloads of emit signal we need
BOOST_PP_REPEAT(5, EMIT_CALL_DEF, ~)
protected:
/*signal handling
* extract all signal types to allow index search (inex search on signal functions would fail as same
* signatures are supported for multiple signals). Create std::vectors to allow multiple slots per signal
* and store these vectors in a fusion::vector for easy access.
* */
typedef typename mpl::fold < SigMap, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::key_type<SigMap, mpl::_2> > >::type sig_name;
typedef typename mpl::fold < SigMap, mpl::vector<>,
mpl::push_back<mpl::_1, mpl::value_type<SigMap, mpl::_2> > >::type sig_functions;
typedef typename mpl::fold < sig_functions, mpl::vector<>,
mpl::push_back<mpl::_1, std::map<int, mpl::_2> > >::type sig_vectors;
typedef typename fusion::result_of::as_vector<sig_vectors>::type Signals;
Signals m_signals;
bool m_emit_signals;
int m_signal_count;
};
/**
* @brief Base class for all object types
*
* This class adds property and signal capabilities to all deriving classes. For properties it is tightly
* integrated with the system class: It searches systems property map for the derived class as specified by
* the second template parameter and makes it accessible via appropriate functions. Signals are specified by a
* mpl::map with signal name type as key and a boost::function as values.
*
* \tparam Sys class of type System of which the properties are taken
* \tparam Obj the type of the derived object
* \tparam Sig an mpl::map specifying the object's signals by (type - boost::function) pairs
**/
template<typename Sys, typename Derived, typename Sig>
struct Object : public PropertyOwner<typename details::properties_by_object<typename Sys::properties, Derived>::type>,
public SignalOwner<Sig>,
boost::enable_shared_from_this<Derived> {
Object() {};
Object(Sys& system);
/**
* @brief Create a new object of the same type with the same values
*
* Returns a new shared_ptr for the Derived type with the same properties as the initial one. If
* the new pointer should be used in a new system the parameter \param newSys needs to be that
* new system. Overload this function if you have datamembers in any derived class which are not
* copyconstructable.
* @tparam Prop property type which should be accessed
* @return Prop::type& a reference to the properties actual value.
**/
virtual std::shared_ptr<Derived> clone(Sys& newSys);
Sys* m_system;
};
}; //dcm
#ifndef DCM_EXTERNAL_CORE
#include "imp/object_imp.hpp"
#endif
#endif //GCM_OBJECT_H

View File

@@ -1,612 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_PROPERTY_H
#define GCM_PROPERTY_H
#include <boost/graph/graph_traits.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/exception/errinfo_errno.hpp>
#include "defines.hpp"
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
/** @addtogroup Core
* @{ */
/** @defgroup Property Properties
*
* @brief Concept and handling of properties for generic data storage and type extension.
*
* Properties are a basic building block of the dcm and fulfill two essential tasks: First, build a
* infrastructure for storing data in any kind of object and second, make this data universally accessible.
* Universally accessible means in this context, that it shall be possible to retrieve data only by
* knowing some kind of identifier. No data type specific get/set functions or access to class members
* should be needed to access the stored values. The usage of identifiers allows to design interfaces
* for properties in a type interchangeable way. Therefore no restrictions are imposed on the interface,
* no matter what or how much data is stored.
*
* The connection of data type and identifier is achieved through the property structs, which all follow
* the same concept: Identifier is the struct type, the stored data is exposed as 'type' typedef. The data
* type can be every c++ type (including classes and structs) which is default constructable. They don't need
* to be assignable or copyable by default, that's only necessary if you want to change the hole stored
* object by assigning. If not, the data object can be uncopyable and it should be used by
* retrieving its reference with get-methods.
*
* Properties are further designed to fit in the concept of compile-time modularisation. To allow the extension
* of all data-holding entities with new data types, properties store their own purpose. That's
* done by extending the property struct with a second typedef which is named kind and which specifies of which
* kind the property is. That means, that this typedef defines when the property shall be used and for which
* context it is designed for. Depending on the properties kind, it will be added to different places inside the dcm.
* A property of kind @ref vertex_property will added to vertices, a property of kind @ref object_property to all
* objects and so on.
*
* If the property type is a standard c++ type like int or bool, the default value can't be set by using its
* constructor. Therefore a interface for setting default values is added to the property. If you want
* to assign a default value you just need to add a struct default_value which returns the wanted default
* value with the operator(). If you don't want a default value, just don't add the struct. The implementation
* assigns the default value to the property, therefore it should only be used with assignable types.
*
*
* A property implementation for storing integers at a graph edge with the identifier
* 'test'property' may look like that:
* @code
* struct test_property {
* typedef int type;
* typedef edge_property kind;
* }
* @endcode
*
* The same property with a default value would be implemented like this:
* @code
* struct test_property {
* typedef int type;
* typedef edge_property kind;
* struct default_value {
* int operator()() {
* return 3;
* };
* };
* }
* @endcode
*
*
* If you want to use properties in your class you should derive from PropertyOwner class, as it does all the
* handling needed and gives you get and set functions which work with the designed identifiers.
*
* @{ */
/**
* @brief Exception for property errors
*
* This exception is thrown when a property related error is detected, for example if an object is asked for a
* property which it does not own. These exceptions own the error-code range from 300-399.
**/
struct property_error : virtual boost::exception { };
/**
* @brief Identifier for vertex properties
*
* This is a identifier structure for vertex properties. Every property with this struct as 'kind' type
* will be added to all vertices of a cluster. It is accessible through global and local vertex
* descriptors. These properties are intended for use in boost algorithms in combination with
* \ref property_map .
*/
struct vertex_property {};
/**
* @brief Identifier for edge properties
*
* This is a identifier structure for edge properties. Every property with this struct as 'kind' type
* will be added to all local edges of a cluster. It is accessible through local edge
* descriptors, or global one by getting its holding local edge first. Note that global edges don't
* have properties, as the properties are intended for use inside boost graph algorithms and therefore
* only needed in local edges. @see property_map
*/
struct edge_property {};
/**
* @brief Identifier for cluster properties
*
* A ClusterGraph has its own properties, and every property with this identifier as 'kind' type will be
* added to it. This is intended for internal dcm usage, it's possible to give the abstract cluster a meaning
* by adding special properties to it. It can be accessed by special ClusterGraph functions designed for this
* purpose.
**/
struct cluster_property {};
/**
*@brief Identifier for general object properties
*
* A property with this struct as 'kind' type will be added to all existing objects, no matter of individual
* type. Use this only for general, shareable properties. To add a property to a single object, use its
* type as 'kind'.
**/
struct object_property {};
/**
*@brief Identifier for system setting properties
*
* A property with this struct as 'kind' type will be added to the system class. Use this for user settings,
* which are just properties which are accessed horugh "setting" functions.
**/
struct setting_property {};
namespace details {
/** @addtogroup Metafunctions
* @{
* @brief Get vertex property information
*
* This traits struct is used to get property information regarding ClusterGraph vertices. It
* allows access to the local descriptor, the mpl property sequence and the position, at which the
* fusion property sequence is stored inside the bundle. It's used to allow generic property
* selection in combination with @ref property_selector
**/
template<typename Graph>
struct vertex_selector {
typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
typedef typename Graph::vertex_properties sequence_type;
typedef mpl::int_<1> property_distance;
};
/** @brief Get edge property information
*
* This traits struct is used to get property information regarding ClusterGraph edges. It
* allows access to the local descriptor, the mpl property sequence and the position, at which the
* fusion property sequence is stored inside the bundle. It's used to allow generic property
* selection in combination with @ref property_selector
**/
template<typename Graph>
struct edge_selector {
typedef typename boost::graph_traits<Graph>::edge_descriptor key_type;
typedef typename Graph::edge_properties sequence_type;
typedef mpl::int_<0> property_distance;
};
/**
* @brief Select property information trait depending on property type
*
* Allows generic access to property information like descriptor or property sequence by exposing
* a specific selector type ( @ref vertex_selector or @ref edge_selector ) depending on the supplied
* property.
**/
template< typename Kind, typename Graph>
struct property_selector : public mpl::if_ < boost::is_same<Kind, vertex_property>,
vertex_selector<Graph>, edge_selector<Graph> >::type {};
/**
* @brief Metafunction to expose the property storage type
**/
template<typename T>
struct property_type {
typedef typename T::type type;
};
/**
* @brief Metafunction to expose which kid of property this is
**/
template<typename T>
struct property_kind {
typedef typename T::kind type;
};
/**
* @brief Metafunction to get all properties for a given kind from a property sequence
**/
template<typename Sequence, typename Kind>
struct properties_by_kind {
typedef typename mpl::fold<Sequence, mpl::vector<>,
mpl::if_<
boost::is_same<Kind, property_kind<mpl::_2> >,
mpl::push_back<mpl::_1, mpl::_2>,
mpl::_1
>
>::type type;
};
/**
* @brief Metafunction to get all properties for a given object from a property sequence. This includes
* the properties with the object types and all general object properties
**/
template<typename Sequence, typename object>
struct properties_by_object {
typedef typename properties_by_kind<Sequence, object>::type object_props;
typedef typename properties_by_kind<Sequence, object_property>::type general_props;
typedef typename mpl::fold< object_props, general_props, mpl::push_back<mpl::_1,mpl::_2> >::type type;
};
/**
* @brief Metafunction to ensures that a property is in a lists
*
* Checks for the existence of a given Property in the mpl::vector supplied and adds the property if it is not found.
* @tparam List mpl::vector with property types
* @tparam Prop the property which should be in the supplied list
**/
template<typename List, typename Prop>
struct ensure_property {
typedef typename mpl::if_ <
boost::is_same <
typename mpl::find<List, Prop>::type,
typename mpl::end<List>::type > ,
typename mpl::push_back<List, Prop>::type,
List >::type type;
};
/**
* @brief Metafunction to ensures that multiple properties are in the lists
*
* Checks for the existence of all Property's given in the mpl::vector supplied and adds the properties if it is not found.
* @tparam List mpl::vector with property types
* @tparam PropList mpl::vector with properties which should be in the supplied list
**/
template<typename List, typename PropList>
struct ensure_properties {
typedef typename mpl::fold < PropList, List,
mpl::if_ <
boost::is_same< mpl::find<mpl::_1, mpl::_2>, mpl::end<mpl::_1> >,
mpl::push_back<mpl::_1, mpl::_2>,
mpl::_1
> >::type type;
};
/**
* @brief Property vector to a fusion sequence of the property storage types
*
* Properties are passed around as mpl sequences, mostly vectors. To store actual values, they need to
* be transformed into fusion sequences. However, only the storage type needs to be in the vector, not
* the 'kind' information (as this is only used as meta information for type creation). This struct
* exposes a fusion vector which can hold all property storage types.
**/
template<typename T>
struct pts { //property type sequence
typedef typename mpl::transform<T, details::property_type<mpl::_1> >::type ptv;
typedef typename fusion::result_of::as_vector< ptv >::type type;
};
/**
* @brief Type traits to detect if the property has a default value
*
* If the user wants to provide a default value for a property than they add a default_value static function.
* To check if the this function is available we add a type traits which searches for this special function.
*/
BOOST_MPL_HAS_XXX_TRAIT_DEF(default_value)
/**@}*/
/**
* @brief Functor to assign default values to property
*
* This functor holds a pointer to the PropertyOwner in question. The operator() gets the properties which
* hold a default value and assigns this value to the property the owner holds.
*/
template<typename PropertyOwner>
struct apply_default {
PropertyOwner* owner;
apply_default(PropertyOwner* o) : owner(o) {};
template<typename T>
void operator()(const T& t) {
owner->template getProperty<T>() = typename T::default_value()();
};
};
}
/** @addtogroup Metafunctions
* @{*/
/**
* @brief Expose if this is a edge property
**/
template<typename T>
struct is_edge_property : boost::is_same<typename T::kind, edge_property> {};
/**
* @brief Expose if this is a vertex property
**/
template<typename T>
struct is_vertex_property : boost::is_same<typename T::kind, vertex_property> {};
/**
* @brief Expose if this is a cluster property
**/
template<typename T>
struct is_cluster_property : boost::is_same<typename T::kind, cluster_property> {};
/**
* @brief Expose if this is a general object property
**/
template<typename T>
struct is_object_property : boost::is_same<typename T::kind, object_property> {};
/**@}*/
/**
* @brief Adapter to use dcm vertex and edge properties as boost property_maps in bgl algorithms
*
* Boost graph algorithms use property maps as generic storage for process data. In most cases the user
* needs to provide these maps. The simplest way is to create them on the stack right before their
* usage. If, however, the stored information is of use and one wants to store it permanently, this way
* is not practical. Therefore vertex and edge properties were introduced, they allow to store arbitrary
* information at their entity. To use this in combination with boost graph algorithms, this class can
* be used to expose vertex and edge properties as propertie maps to the boost algorithms. All process
* information is then stored permanently at the relevant position.
**/
template <typename Property, typename Graph>
class property_map {
public:
//expose boost property map interface types
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::key_type key_type;
typedef typename Property::type value_type;
typedef typename Property::type& reference;
typedef boost::lvalue_property_map_tag category;
//expose custom types for easy access
typedef Property property;
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::sequence_type sequence;
typedef typename dcm::details::property_selector<typename Property::kind, Graph>::property_distance distance;
/**
* @brief Links property map with the ClusterGraph which shall be accessed
*
* As boost graph algorithms work with local descriptors, the property map needs to know in which
* graph they are valid. this graph has to be passed to the map. Of course this has to be the one
* on which the algorithm is used on
*
* @param g shared ptr of the cluster graph on which the algorithm is used
**/
property_map(std::shared_ptr<Graph> g)
: m_graph(g) { }
std::shared_ptr<Graph> m_graph;
};
/**
* @brief Parent class for all property holding classes in the dcm
*
* To ease the work with properties this class is provided. It receives all the properties, which shall be
* handled, in a mpl::vector typelist as its template argument. Than easy access to all properties by get
* and set functions is achieved.
*
**/
template<typename PropertyList>
struct PropertyOwner {
/**
* @brief Constructor assigning default values
*
* It's important to initialise the property fusion sequences with this constructor
* as much handling has to be done to ensure the users default values are added correctly
**/
PropertyOwner();
/**
* @brief Access properties
*
* Returns a reference to the properties actual value. The property type has to be owned by this class,
* which means it needs to be in the typelist that was given as template parameter to this class.
* @tparam Prop property type which should be accessed
* @return Prop::type& a reference to the properties actual value.
**/
template<typename Prop>
typename Prop::type& getProperty();
/**
* @brief Set properties
*
* Sets the value of a specified property. The property type has to be owned by this class,
* which means it needs to be in the typelist that was given as template parameter to this class.
* Note that setProperty(value) is equivalent to getProperty() = value.
* @tparam Prop property type which should be setProperty
* @param value value of type Prop::type which should be set in this object
**/
template<typename Prop>
void setProperty(typename Prop::type value);
/* It's imortant to not store the properties but their types. These types are
* stored and accessed as fusion vector.
* */
typedef PropertyList PropertySequence;
typedef typename details::pts<PropertyList>::type Properties;
Properties m_properties;
};
template<typename PropertyList>
PropertyOwner<PropertyList>::PropertyOwner() {
//get a vies of all types which have a default value
typedef typename mpl::filter_view<PropertyList, details::has_default_value<mpl::_> >::type view;
//set the default value
details::apply_default<PropertyOwner> func(this);
mpl::for_each<view>(func);
#if defined(BOOST_MPL_CFG_NO_HAS_XXX)
throw property_error() << boost::errinfo_errno(301) << error_message("no default values supported");
#endif
};
/**
* @brief Convenience specialization to ease interaction with system class
*
* Normally property lists are retrieved from the system class, however, there are no empty lists. If no
* property is supplied for a PropertyOwner derived class, a mpl::void_ type will be retrieved. To
* remove the burden of checking for that type in the class definition this specialization is supplied.
**/
template<>
struct PropertyOwner<mpl::void_> {
template<typename Prop>
typename Prop::type& getProperty() {
throw property_error() << boost::errinfo_errno(300) << error_message("unknown property type");
};
template<typename Prop>
void setProperty(typename Prop::type value) {
throw property_error() << boost::errinfo_errno(300) << error_message("unknown property type");
};
};
template<typename PropertyList>
template<typename Prop>
typename Prop::type& PropertyOwner<PropertyList>::getProperty() {
typedef typename mpl::find<PropertyList, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<PropertyList>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<PropertyList>::type > >));
return fusion::at<distance> (m_properties);
};
template<typename PropertyList>
template<typename Prop>
void PropertyOwner<PropertyList>::setProperty(typename Prop::type value) {
typedef typename mpl::find<PropertyList, Prop>::type iterator;
typedef typename mpl::distance<typename mpl::begin<PropertyList>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<PropertyList>::type > >));
fusion::at<distance> (m_properties) = value;
};
//now create some standard properties
//***********************************
/**
* @brief Dummy property
**/
struct empty_prop {
typedef int kind;
typedef int type;
};
//type of a graph cluster
/**
* @brief Add a type to clusters
*
* Allows to specify special types to ClusterGraphs and make a it possible to distinguish between
* different purposes. The cluster types need to be int.
**/
struct type_prop {
//states the type of a cluster
typedef cluster_property kind;
typedef int type;
};
//cluster in graph changed?
/**
* @brief Was the cluster changed?
*
* Adds a boolean to the cluster which indicates if the cluster was changed since the last
* processing. It should be set to true if vertices and edges were added or removed, Subclusters
* created or deleted and so on.
**/
struct changed_prop {
typedef cluster_property kind;
typedef bool type;
};
/**
* @brief Add an index to vertices
*
* Most boost graph algorithms need a index for vertices, ranging from 0 to vertex count. As this can
* be useful for many other things it is added as vertex property.
**/
struct vertex_index_prop {
typedef vertex_property kind;
typedef int type;
};
/**
* @brief Add an index to edges
*
* Most boost graph algorithms need a index for edges, ranging from 0 to edge count. As this can
* be useful for many other things it is added as edge property.
**/
struct edge_index_prop {
typedef edge_property kind;
typedef int type;
};
/**
* @brief Add an ID to objects
*
* It may be wanted to add identification markers to objects, this property can be used for that. It
* is special, as it takes its storage type as template parameter. This property can therefore not be
* directly accessed with this struct, the template parameter has to be known.
* @tparam T the identifier type
**/
template<typename T>
struct id_prop {
typedef object_property kind;
typedef T type;
};
/**@}*/ //Property
/**@}*/ //Core
}
namespace boost {
//access the propertymap needs to be boost visible
template<typename P, typename G>
typename dcm::property_map<P, G>::value_type get(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key)
{
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
return fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key)));
};
template <typename P, typename G>
void put(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key,
const typename dcm::property_map<P, G>::value_type& value)
{
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key))) = value;
};
template <typename P, typename G>
typename dcm::property_map<P, G>::reference at(const dcm::property_map<P, G>& map,
typename dcm::property_map<P, G>::key_type key)
{
typedef dcm::property_map<P, G> map_t;
typedef typename mpl::find<typename map_t::sequence, typename map_t::property>::type iterator;
typedef typename mpl::distance<typename mpl::begin<typename map_t::sequence>::type, iterator>::type distance;
return fusion::at<distance> (fusion::at<typename dcm::property_map<P, G>::distance> (map.m_graph->operator[](key)));
}
}
#endif //GCM_PROPERTY_H

View File

@@ -1,100 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_SCHEDULER_H
#define GCM_SCHEDULER_H
#include <set>
#include <algorithm>
namespace dcm {
template<typename Sys>
struct Job {
virtual ~Job() {};
virtual void execute(Sys& sys) = 0;
bool operator<(const Job<Sys>& j) const {
return priority < j.priority;
};
int priority;
};
template<typename functor, typename System, int prior>
struct FunctorJob : Job<System> {
FunctorJob(functor f) : m_functor(f) {
Job<System>::priority = prior;
};
virtual void execute(System& sys) {
m_functor(sys);
};
functor m_functor;
};
template<typename Sys>
class Sheduler {
public:
Sheduler() {};
~Sheduler() {
std::for_each(m_preprocess.begin(), m_preprocess.end(), Deleter());
std::for_each(m_process.begin(), m_process.end(), Deleter());
std::for_each(m_postprocess.begin(), m_postprocess.end(), Deleter());
};
void addPreprocessJob(Job<Sys>* j) {
m_preprocess.insert(j);
};
void addPostprocessJob(Job<Sys>* j) {
m_postprocess.insert(j);
};
void addProcessJob(Job<Sys>* j) {
m_process.insert(j);
};
void execute(Sys& system) {
std::for_each(m_preprocess.begin(), m_preprocess.end(), Executer(system));
std::for_each(m_process.begin(), m_process.end(), Executer(system));
std::for_each(m_postprocess.begin(), m_postprocess.end(), Executer(system));
};
protected:
struct Executer {
Executer(Sys& s) : m_system(s) {};
void operator()(Job<Sys>* j) {
j->execute(m_system);
};
Sys& m_system;
};
struct Deleter {
void operator()(Job<Sys>* j) {
delete j;
};
};
std::set< Job<Sys>* > m_preprocess, m_process, m_postprocess;
};
}
#endif //GCM_SCHEDULER_H

View File

@@ -1,400 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_SYSTEM_H
#define GCM_SYSTEM_H
#include <boost/mpl/vector.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/vector/vector0.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/count.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/function.hpp>
#include "property.hpp"
#include "clustergraph.hpp"
#include "scheduler.hpp"
#include "logging.hpp"
#include "traits.hpp"
#include "object.hpp"
#include "kernel.hpp"
namespace mpl = boost::mpl;
namespace fusion = boost::fusion;
namespace dcm {
struct No_Identifier {}; //struct to show that no identifier shall be used
struct Unspecified_Identifier {}; //struct to show that it doesn't matter which identifier type is used
struct solved {}; //signal emitted when solving is done
namespace details {
enum { subcluster = 10};
/**
* @brief Appends a mpl sequences to another
*
* Makes two sequence to one by appending all types of the first to the second sequence. The new
* mpl sequence can be accessed by the ::type typedef.
* Usage: @code vector_fold<Seq1, Seq2>::type @endcode
*
* @tparam state the mpl sequence which will be expanded
* @tparam seq the mpl sequence which will be appended
**/
template<typename seq, typename state>
struct vector_fold : mpl::fold < seq, state,
mpl::push_back<mpl::_1, mpl::_2> > {};
template<typename seq, typename state>
struct edge_fold : mpl::fold< seq, state,
mpl::if_< is_edge_property<mpl::_2>,
mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};
template<typename seq, typename state>
struct vertex_fold : mpl::fold< seq, state,
mpl::if_< is_vertex_property<mpl::_2>,
mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};
template<typename seq, typename state>
struct cluster_fold : mpl::fold< seq, state,
mpl::if_< is_cluster_property<mpl::_2>,
mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};
template<typename seq, typename state, typename obj>
struct obj_fold : mpl::fold< seq, state,
mpl::if_< mpl::or_<
boost::is_same< details::property_kind<mpl::_2>, obj>, is_object_property<mpl::_2> >,
mpl::push_back<mpl::_1,mpl::_2>, mpl::_1 > > {};
template<typename T>
struct get_identifier {
typedef typename T::Identifier type;
};
template<typename seq, typename state>
struct map_fold : mpl::fold< seq, state, mpl::insert<mpl::_1,mpl::_2> > {};
template<typename state, typename seq1, typename seq2, typename seq3>
struct map_fold_3 {
typedef typename details::map_fold<seq1,
typename details::map_fold<seq2,
typename details::map_fold<seq3,
state >::type >::type>::type type;
};
struct nothing {};
template<int v>
struct EmptyModule {
template<typename T>
struct type {
struct inheriter {
void system_sub(std::shared_ptr<T> subsys) {};
};
typedef mpl::vector<> properties;
typedef mpl::vector<> objects;
typedef mpl::vector<> geometries;
typedef mpl::map<> signals;
typedef Unspecified_Identifier Identifier;
static void system_init(T& sys) {};
static void system_copy(const T& from, T& into) {};
};
};
template <class T>
struct is_shared_ptr : boost::mpl::false_ {};
template <class T>
struct is_shared_ptr<std::shared_ptr<T> > : boost::mpl::true_ {};
template<typename Sys, typename M1, typename M2, typename M3>
struct inheriter : public M1::inheriter, public M2::inheriter, public M3::inheriter,
dcm::SignalOwner<typename details::map_fold_3< mpl::map<mpl::pair<solved, boost::function<void (Sys*)> > >,
typename M1::signals, typename M2::signals, typename M3::signals>::type> {};
}
template< typename KernelType,
typename T1 = details::EmptyModule<1>,
typename T2 = details::EmptyModule<2>,
typename T3 = details::EmptyModule<3> >
class System : public details::inheriter<System<KernelType,T1,T2,T3>, typename T1::template type< System<KernelType,T1,T2,T3> >,
typename T2::template type< System<KernelType,T1,T2,T3> >,
typename T3::template type< System<KernelType,T1,T2,T3> > > {
typedef System<KernelType,T1,T2,T3> BaseType;
public:
typedef T1 Module1;
typedef T2 Module2;
typedef T3 Module3;
typedef typename T1::template type< BaseType > Type1;
typedef typename T2::template type< BaseType > Type2;
typedef typename T3::template type< BaseType > Type3;
typedef mpl::vector3<Type1, Type2, Type3> TypeVector;
typedef typename Type1::inheriter Inheriter1;
typedef typename Type2::inheriter Inheriter2;
typedef typename Type3::inheriter Inheriter3;
//Check if all Identifiers are the same and find out which type it is
typedef typename mpl::fold<TypeVector, mpl::vector<>,
mpl::if_<boost::is_same<details::get_identifier<mpl::_2>, Unspecified_Identifier>,
mpl::_1, mpl::push_back<mpl::_1, details::get_identifier<mpl::_2> > > >::type Identifiers;
BOOST_MPL_ASSERT((mpl::or_<
mpl::less_equal<typename mpl::size<Identifiers>::type, mpl::int_<1> >,
mpl::equal< typename mpl::count<Identifiers,
typename mpl::at_c<Identifiers,0> >::type, typename mpl::size<Identifiers>::type > >));
typedef typename mpl::if_< mpl::empty<Identifiers>,
No_Identifier, typename mpl::at_c<Identifiers, 0>::type >::type Identifier;
public:
//get all module objects and properties
typedef typename details::vector_fold<typename Type3::objects,
typename details::vector_fold<typename Type2::objects,
typename details::vector_fold<typename Type1::objects,
mpl::vector<> >::type >::type>::type objects;
typedef typename details::vector_fold<typename Type3::properties,
typename details::vector_fold<typename Type2::properties,
typename details::vector_fold<typename Type1::properties,
mpl::vector<id_prop<Identifier> > >::type >::type>::type properties;
//get all geometries we support
typedef typename details::vector_fold<typename Type3::geometries,
typename details::vector_fold<typename Type2::geometries,
typename details::vector_fold<typename Type1::geometries,
mpl::vector<> >::type >::type>::type geometries;
//make the subcomponent lists of objects and properties
typedef typename details::edge_fold< properties,
mpl::vector1<edge_index_prop> >::type edge_properties;
typedef typename details::vertex_fold< properties,
mpl::vector1<vertex_index_prop> >::type vertex_properties;
typedef typename details::cluster_fold< properties,
mpl::vector2<changed_prop, type_prop> >::type cluster_properties;
//we hold our own PropertyOwner which we use for system settings. Don't inherit it as the user
//should not access the settings via the property getter and setter functions.
typedef PropertyOwner<typename details::properties_by_kind<properties, setting_property>::type> OptionOwner;
std::shared_ptr<OptionOwner> m_options;
protected:
//object storage
typedef typename mpl::transform<objects, std::shared_ptr<mpl::_1> >::type sp_objects;
typedef typename mpl::fold< sp_objects, mpl::vector<>,
mpl::push_back<mpl::_1, std::vector<mpl::_2> > >::type object_vectors;
typedef typename fusion::result_of::as_vector<object_vectors>::type Storage;
template<typename FT1, typename FT2, typename FT3>
friend struct Object;
#ifdef USE_LOGGING
std::shared_ptr< sink_t > sink;
#endif
public:
typedef ClusterGraph<edge_properties, vertex_properties, cluster_properties, objects> Cluster;
typedef Scheduler< BaseType > Schedule;
typedef KernelType Kernel;
public:
System();
~System();
void clear();
template<typename Object>
typename std::vector< std::shared_ptr<Object> >::iterator begin();
template<typename Object>
typename std::vector< std::shared_ptr<Object> >::iterator end();
template<typename Object>
std::vector< std::shared_ptr<Object> >& objectVector();
template<typename Object>
void push_back(std::shared_ptr<Object> ptr);
template<typename Object>
void erase(std::shared_ptr<Object> ptr);
SolverInfo solve();
std::shared_ptr< System > createSubsystem();
typename std::vector< std::shared_ptr<System> >::iterator beginSubsystems();
typename std::vector< std::shared_ptr<System> >::iterator endSubsystems();
//a kernel has it's own settings, therefore we need to decide which is accessed
template<typename Option>
typename boost::enable_if< boost::is_same< typename mpl::find<typename Kernel::PropertySequence, Option>::type,
typename mpl::end<typename Kernel::PropertySequence>::type >, typename Option::type& >::type getOption();
template<typename Option>
typename boost::disable_if< boost::is_same< typename mpl::find<typename Kernel::PropertySequence, Option>::type,
typename mpl::end<typename Kernel::PropertySequence>::type >, typename Option::type& >::type getOption();
template<typename Option>
typename boost::enable_if< boost::is_same< typename mpl::find<typename Kernel::PropertySequence, Option>::type,
typename mpl::end<typename Kernel::PropertySequence>::type >, void >::type setOption(typename Option::type value);
template<typename Option>
typename boost::disable_if< boost::is_same< typename mpl::find<typename Kernel::PropertySequence, Option>::type,
typename mpl::end<typename Kernel::PropertySequence>::type >, void >::type setOption(typename Option::type value);
//convenience function
template<typename Option>
typename Option::type& option();
//let evryone access and use our math kernel
Kernel& kernel();
void copyInto(System& into) const;
System* clone() const;
std::shared_ptr<Cluster> m_cluster;
std::shared_ptr<Storage> m_storage;
Schedule m_scheduler;
Kernel m_kernel;
std::vector<std::shared_ptr<System> > m_subsystems;
#ifdef USE_LOGGING
template<typename Expr>
void setLoggingFilter(const Expr& ex) {
sink->set_filter(ex);
}
#endif
};
//implementations which always need to be with the definition as they can't be externalised
//*****************************************************************************************
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Object>
typename std::vector< std::shared_ptr<Object> >::iterator System<KernelType, T1, T2, T3>::begin() {
typedef typename mpl::find<objects, Object>::type iterator;
typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
return fusion::at<distance>(*m_storage).begin();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Object>
typename std::vector< std::shared_ptr<Object> >::iterator System<KernelType, T1, T2, T3>::end() {
typedef typename mpl::find<objects, Object>::type iterator;
typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
return fusion::at<distance>(*m_storage).end();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Object>
std::vector< std::shared_ptr<Object> >& System<KernelType, T1, T2, T3>::objectVector() {
typedef typename mpl::find<objects, Object>::type iterator;
typedef typename mpl::distance<typename mpl::begin<objects>::type, iterator>::type distance;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<iterator, typename mpl::end<objects>::type > >));
return fusion::at<distance>(*m_storage);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Object>
void System<KernelType, T1, T2, T3>::push_back(std::shared_ptr<Object> ptr) {
objectVector<Object>().push_back(ptr);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Object>
void System<KernelType, T1, T2, T3>::erase(std::shared_ptr<Object> ptr) {
std::vector< std::shared_ptr<Object> >& vec = objectVector<Object>();
vec.erase(std::remove(vec.begin(), vec.end(), ptr), vec.end());
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Option>
typename boost::enable_if< boost::is_same< typename mpl::find<typename KernelType::PropertySequence, Option>::type,
typename mpl::end<typename KernelType::PropertySequence>::type >, typename Option::type& >::type
System<KernelType, T1, T2, T3>::getOption() {
return m_options->template getProperty<Option>();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Option>
typename boost::disable_if< boost::is_same< typename mpl::find<typename KernelType::PropertySequence, Option>::type,
typename mpl::end<typename KernelType::PropertySequence>::type >, typename Option::type& >::type
System<KernelType, T1, T2, T3>::getOption() {
return m_kernel.template getProperty<Option>();
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Option>
typename boost::enable_if< boost::is_same< typename mpl::find<typename KernelType::PropertySequence, Option>::type,
typename mpl::end<typename KernelType::PropertySequence>::type >, void >::type
System<KernelType, T1, T2, T3>::setOption(typename Option::type value) {
m_options->template setProperty<Option>(value);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Option>
typename boost::disable_if< boost::is_same< typename mpl::find<typename KernelType::PropertySequence, Option>::type,
typename mpl::end<typename KernelType::PropertySequence>::type >, void >::type
System<KernelType, T1, T2, T3>::setOption(typename Option::type value) {
m_kernel.template setProperty<Option>(value);
};
template< typename KernelType, typename T1, typename T2, typename T3 >
template<typename Option>
typename Option::type&
System<KernelType, T1, T2, T3>::option() {
return getOption<Option>();
};
}
#ifndef DCM_EXTERNAL_CORE
#include "imp/system_imp.hpp"
#endif
#endif //GCM_SYSTEM_H

View File

@@ -1,75 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_TRAITS_H
#define DCM_TRAITS_H
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/void.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/at.hpp>
#include <string.h>
namespace mpl = boost::mpl;
namespace dcm {
template< typename T >
struct system_traits {
//typedef typename T::Kernel Kernel;
//typedef typename T::Cluster Cluster;
template<typename M>
struct getModule {
typedef typename mpl::if_< boost::is_base_of<M, typename T::Type1>, typename T::Type1, typename T::Type2 >::type test1;
typedef typename mpl::if_< boost::is_base_of<M, test1>, test1, typename T::Type3 >::type test2;
typedef typename mpl::if_< boost::is_base_of<M, test2>, test2, mpl::void_ >::type type;
typedef mpl::not_<boost::is_same<type, mpl::void_> > has_module;
};
};
template<typename T>
struct compare_traits {
BOOST_MPL_ASSERT_MSG((mpl::not_<boost::is_same<T, const char*> >::value),
YOU_SHOULD_NOT_USE_THIS_TYPE_AS_IDENTIFIER,
(const char*));
static bool compare(T& first, T& second) {
return first == second;
};
};
template<>
struct compare_traits<std::string> {
static bool compare(std::string& first, std::string& second) {
return !(first.compare(second));
};
};
}//namespace dcm
#endif //GCM_TRAITS_H

View File

@@ -1,167 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_TRANSFORMATION_H
#define DCM_TRANSFORMATION_H
#include <cmath>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <boost/mpl/if.hpp>
namespace dcm {
namespace detail {
template<typename Scalar, int Dim>
class Transform {
public:
typedef Eigen::Matrix<Scalar, Dim, 1> Vector;
typedef typename boost::mpl::if_c< Dim == 3,
Eigen::Quaternion<Scalar>,
Eigen::Rotation2D<Scalar> >::type Rotation;
typedef Eigen::Translation<Scalar, Dim> Translation;
typedef Eigen::UniformScaling<Scalar> Scaling;
typedef typename Rotation::RotationMatrixType RotationMatrix;
protected:
Rotation m_rotation;
Translation m_translation;
Scaling m_scale;
public:
Transform();
Transform(const Rotation& r);
Transform(const Rotation& r, const Translation& t);
Transform(const Rotation& r, const Translation& t, const Scaling& s);
//access the single parts and manipulate them
//***********************
const Rotation& rotation() const;
template<typename Derived>
Transform& setRotation(const Eigen::RotationBase<Derived,Dim>& rotation);
template<typename Derived>
Transform& rotate(const Eigen::RotationBase<Derived,Dim>& rotation);
const Translation& translation() const;
Transform& setTranslation(const Translation& translation);
Transform& translate(const Translation& translation);
const Scaling& scaling() const;
Transform& setScale(const Scaling& scaling);
Transform& scale(const Scalar& scaling);
Transform& scale(const Scaling& scaling);
Transform& invert();
Transform inverse();
//operators for value manipulation
//********************************
Transform& operator=(const Translation& t);
Transform operator*(const Translation& s) const;
Transform& operator*=(const Translation& t);
Transform& operator=(const Scaling& s);
Transform operator*(const Scaling& s) const;
Transform& operator*=(const Scaling& s);
template<typename Derived>
Transform& operator=(const Eigen::RotationBase<Derived,Dim>& r);
template<typename Derived>
Transform operator*(const Eigen::RotationBase<Derived,Dim>& r) const;
template<typename Derived>
Transform& operator*=(const Eigen::RotationBase<Derived,Dim>& r);
Transform operator* (const Transform& other) const;
Transform& operator*= (const Transform& other);
//transform Vectors
//*****************
template<typename Derived>
Derived& rotate(Eigen::MatrixBase<Derived>& vec) const;
template<typename Derived>
Derived& translate(Eigen::MatrixBase<Derived>& vec) const;
template<typename Derived>
Derived& scale(Eigen::MatrixBase<Derived>& vec) const;
template<typename Derived>
Derived& transform(Eigen::MatrixBase<Derived>& vec) const;
template<typename Derived>
Derived operator*(const Eigen::MatrixBase<Derived>& vec) const;
template<typename Derived>
void operator()(Eigen::MatrixBase<Derived>& vec) const;
//Stuff
//*****
bool isApprox(const Transform& other, Scalar prec) const;
void setIdentity();
static const Transform Identity();
Transform& normalize();
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
template<typename Scalar, int Dim>
class DiffTransform : public Transform<Scalar, Dim> {
typedef typename Transform<Scalar, Dim>::Rotation Rotation;
typedef typename Transform<Scalar, Dim>::Translation Translation;
typedef typename Transform<Scalar, Dim>::Scaling Scaling;
typedef Eigen::Matrix<Scalar, Dim, 3*Dim> DiffMatrix;
DiffMatrix m_diffMatrix;
public:
DiffTransform() : Transform<Scalar, Dim>() { };
DiffTransform(const Rotation& r) : Transform<Scalar, Dim>(r) {};
DiffTransform(const Rotation& r, const Translation& t) : Transform<Scalar, Dim>(r,t) {};
DiffTransform(const Rotation& r, const Translation& t, const Scaling& s) : Transform<Scalar, Dim>(r,t,s) {};
DiffTransform(Transform<Scalar, Dim>& trans);
const DiffMatrix& differential();
Scalar& operator()(int f, int s);
Scalar& at(int f, int s);
};
/*When you overload a binary operator as a member function of a class the overload is used
* when the first operand is of the class type.For stream operators, the first operand
* is the stream and not (usually) the custom class.
*/
template<typename charT, typename traits, typename Kernel, int Dim>
std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& os, const dcm::detail::Transform<Kernel, Dim>& t);
template<typename charT, typename traits,typename Kernel, int Dim>
std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& os, dcm::detail::DiffTransform<Kernel, Dim>& t);
}//detail
}//DCM
//#ifndef DCM_EXTERNAL_CORE
#include "imp/transformation_imp.hpp"
//#endif
#endif //DCM_TRANSFORMATION

View File

@@ -1,78 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EXTERNALIZE_H
#define DCM_EXTERNALIZE_H
#ifdef _WIN32
//warning about excessively long decorated names, won't affect the code correctness
#pragma warning( disable : 4503 )
#endif
#include <boost/preprocessor/list/for_each.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/list/append.hpp>
#ifdef USE_EXTERNAL
#define DCM_EXTERNAL_INCLUDE_001 <opendcm/moduleState/edge_vertex_generator_imp.hpp>
#define DCM_EXTERNAL_001( System )\
template struct dcm::details::edge_generator<System>; \
template struct dcm::details::vertex_generator<System>; \
#define DCM_EXTERNAL_INCLUDE_002 <opendcm/moduleState/object_generator_imp.hpp>
#define DCM_EXTERNAL_002( System )\
template struct dcm::details::obj_gen<System>; \
#define DCM_EXTERNAL_INCLUDE_003 <opendcm/moduleState/property_generator_imp.hpp>
#define DCM_EXTERNAL_003( System )\
template struct dcm::details::vertex_prop_gen<System>; \
template struct dcm::details::edge_prop_gen<System>; \
template struct dcm::details::cluster_prop_gen<System>;
#define DCM_EXTERNAL_INCLUDE_004 <opendcm/moduleState/generator_imp.hpp>
#define DCM_EXTERNAL_004( System )\
template struct dcm::generator<System>; \
#define DCM_EXTERNAL_INCLUDE_005 <opendcm/moduleState/property_parser_imp.hpp>
#define DCM_EXTERNAL_005( System )\
template struct dcm::details::vertex_prop_par<System>; \
template struct dcm::details::edge_prop_par<System>; \
template struct dcm::details::cluster_prop_par<System>;
#define DCM_EXTERNAL_INCLUDE_006 <opendcm/moduleState/object_parser_imp.hpp>
#define DCM_EXTERNAL_006( System )\
template struct dcm::details::obj_par<System>; \
#define DCM_EXTERNAL_INCLUDE_007 <opendcm/moduleState/edge_vertex_parser_imp.hpp>
#define DCM_EXTERNAL_007( System )\
template struct dcm::details::edge_parser<System>; \
template struct dcm::details::vertex_parser<System>; \
#define DCM_EXTERNAL_INCLUDE_008 <opendcm/moduleState/parser_imp.hpp>
#define DCM_EXTERNAL_008( System )\
template struct dcm::parser<System>; \
#else
#define DCM_EXTERNALIZE( System )
#endif
#endif //DCM_EXTERNALIZE_H

View File

@@ -1,73 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE3D_H
#define DCM_MODULE3D_H
#define DCM_USE_MODULE3D
#ifdef _WIN32
//warning about excessively long decorated names, won't affect the code correctness
#pragma warning( disable : 4503 )
#endif
#include "module3d/defines.hpp"
#include "module3d/geometry.hpp"
#include "module3d/distance.hpp"
#include "module3d/parallel.hpp"
#include "module3d/angle.hpp"
#include "module3d/coincident.hpp"
#include "module3d/alignment.hpp"
#include "module3d/module.hpp"
#ifdef DCM_USE_MODULESTATE
#include "module3d/state.hpp"
#endif //use state
#ifdef DCM_EXTERNAL_3D
#define DCM_EXTERNAL_3D_INCLUDE_01 "opendcm/module3d/imp/clustermath_imp.hpp"
#define DCM_EXTERNAL_3D_01( Sys )\
template struct dcm::details::ClusterMath<Sys>;\
template struct dcm::details::MES<Sys>;\
template struct Sys::Kernel::MappedEquationSystem;\
template struct dcm::details::SystemSolver<Sys>;
#define DCM_EXTERNAL_3D_INCLUDE_02 "opendcm/module3d/imp/constraint3d_holder_imp.hpp"
#define DCM_EXTERNAL_3D_02( System )\
INITIALIZE(System, 3, CONSTRAINT_SEQUENCE);
#define DCM_EXTERNAL_3D_INCLUDE_03 <opendcm/module3d/imp/state_imp.hpp>
#define DCM_EXTERNAL_3D_03( System )\
template struct dcm::parser_generator< dcm::details::getModule3D< System >::type::Geometry3D , System, std::ostream_iterator<char> >; \
template struct dcm::parser_generator< dcm::details::getModule3D<System>::type::vertex_prop , System, std::ostream_iterator<char> >; \
template struct dcm::parser_generator< dcm::details::getModule3D<System>::type::Constraint3D , System, std::ostream_iterator<char> >; \
template struct dcm::parser_generator< dcm::details::getModule3D<System>::type::edge_prop , System, std::ostream_iterator<char> >; \
template struct dcm::parser_generator< dcm::details::getModule3D<System>::type::fix_prop, System, std::ostream_iterator<char> >; \
template struct dcm::parser_parser< dcm::details::getModule3D<System>::type::edge_prop, System, boost::spirit::istream_iterator >; \
template struct dcm::parser_parser< dcm::details::getModule3D<System>::type::vertex_prop, System, boost::spirit::istream_iterator >; \
template struct dcm::parser_parser< dcm::details::getModule3D<System>::type::fix_prop, System, boost::spirit::istream_iterator >; \
template struct dcm::parser_parser< dcm::details::getModule3D<System>::type::Geometry3D, System, boost::spirit::istream_iterator >; \
template struct dcm::parser_parser< dcm::details::getModule3D<System>::type::Constraint3D, System, boost::spirit::istream_iterator >;
#endif //external 3d
#endif //DCM_MODULE3D_H

View File

@@ -1,133 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_ALIGNMENT_HPP
#define DCM_ALIGNMENT_HPP
#include <opendcm/core/equations.hpp>
#include "distance.hpp"
#include "coincident.hpp"
namespace dcm {
namespace details {
//we need a custom orientation type to allow coincidents with points. We can't use the ci_orientation
//as some geometries are supported by align but not by coincident
struct al_orientation : public Equation<al_orientation, Direction, 6, rotation> {
using Equation::operator=;
using Equation::options;
al_orientation() : Equation() {
setDefault();
};
al_orientation& operator=(const al_orientation& d) {
return Equation::assign(d);
};
void setDefault() {
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(103) << error_message("unsupported geometry in alignment orientation constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
typename al_orientation::options values;
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::line3D, tag::line3D > : public ci_orientation::type< Kernel, tag::line3D, tag::line3D > {};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::line3D, tag::plane3D > : public ci_orientation::type< Kernel, tag::line3D, tag::plane3D > {};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::line3D, tag::cylinder3D > : public ci_orientation::type< Kernel, tag::line3D, tag::cylinder3D > {};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::plane3D, tag::plane3D > : public ci_orientation::type< Kernel, tag::plane3D, tag::plane3D > {};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::plane3D, tag::cylinder3D > : public dcm::Orientation::type< Kernel, tag::plane3D, tag::cylinder3D > {
//we misuse the scale method to change whatever direction was set to the only valid one: perpendicular
void setScale(typename Kernel::number_type scale) {
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::plane3D >::values).second = perpendicular;
};
};
template< typename Kernel >
struct al_orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public ci_orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > {};
}; //namespace details
//use al_orientation to ensure the correct orientations for alignment (distance is only defined for special
//orientations)
struct Alignment : public constraint_sequence< fusion::vector2< Distance, details::al_orientation >, Alignment > {
using constraint_sequence::operator=;
};
static Alignment alignment;
}//dcm
#endif //DCM_ALIGNMENT_HPP

View File

@@ -1,178 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_ANGLE_HPP
#define GCM_ANGLE_HPP
#include "geometry.hpp"
#include <opendcm/core/equations.hpp>
namespace dcm {
//the calculations( same as we always calculate directions we can outsource the work to this functions)
namespace angle_detail {
template<typename Kernel, typename T1, typename T2>
inline typename Kernel::number_type calc(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const typename Kernel::number_type& angle) {
return d1.dot(d2) / (d1.norm()*d2.norm()) - std::cos(angle);
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline typename Kernel::number_type calcGradFirst(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& dd1) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
return dd1.dot(d2)/norm - (d1.dot(d2) * (d1.dot(dd1)/d1.norm())*d2.norm()) / std::pow(norm,2);
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline typename Kernel::number_type calcGradSecond(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& dd2) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
return d1.dot(dd2)/norm - (d1.dot(d2) * (d2.dot(dd2)/d2.norm())*d1.norm()) / std::pow(norm,2);
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline void calcGradFirstComp(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& grad) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
const_cast< E::MatrixBase<T3>& >(grad) = d2/norm - d1.dot(d2)*d1/(std::pow(d1.norm(),3)*d2.norm());
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline void calcGradSecondComp(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& grad) {
typename Kernel::number_type norm = d1.norm()*d2.norm();
const_cast< E::MatrixBase<T3>& >(grad) = d1/norm - d1.dot(d2)*d2/(std::pow(d2.norm(),3)*d1.norm());
};
}
template< typename Kernel >
struct Angle::type< Kernel, tag::line3D, tag::line3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typename Angle::options values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return angle_detail::calc<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), fusion::at_key<double>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return angle_detail::calcGradFirst<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), dparam1.template segment<3>(3));
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return angle_detail::calcGradSecond<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), dparam2.template segment<3>(3));
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
angle_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), gradient.template segment<3>(3));
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
angle_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3), param2.template segment<3>(3), gradient.template segment<3>(3));
};
};
template< typename Kernel >
struct Angle::type< Kernel, tag::line3D, tag::plane3D > : public Angle::type<Kernel, tag::line3D, tag::line3D> {};
template< typename Kernel >
struct Angle::type< Kernel, tag::line3D, tag::cylinder3D > : public Angle::type<Kernel, tag::line3D, tag::line3D> {
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Angle::type<Kernel, tag::line3D, tag::line3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
template< typename Kernel >
struct Angle::type< Kernel, tag::plane3D, tag::plane3D > : public Angle::type<Kernel, tag::line3D, tag::line3D> {};
template< typename Kernel >
struct Angle::type< Kernel, tag::plane3D, tag::cylinder3D > : public Angle::type<Kernel, tag::line3D, tag::line3D> {
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Angle::type<Kernel, tag::line3D, tag::line3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
template< typename Kernel >
struct Angle::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public Angle::type<Kernel, tag::line3D, tag::line3D> {
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Angle::type<Kernel, tag::line3D, tag::line3D>::calculateGradientFirstComplete(param1, param2, gradient);
gradient(6)=0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Angle::type<Kernel, tag::line3D, tag::line3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
}
#endif //GCM_ANGLE_HPP

View File

@@ -1,161 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CLUSTERMATH_H
#define DCM_CLUSTERMATH_H
#include <vector>
#include <Eigen/StdVector>
#include <boost/noncopyable.hpp>
#include <opendcm/core/logging.hpp>
#include <opendcm/core/kernel.hpp>
#include "defines.hpp"
#define MAXFAKTOR 1.2 //the maximal distance allowed by a point normed to the cluster size
#define MINFAKTOR 0.8 //the minimal distance allowed by a point normed to the cluster size
#define SKALEFAKTOR 1. //the faktor by which the biggest size is multiplied to get the scale value
#define NQFAKTOR 0.5 //the faktor by which the norm quaternion is multiplied with to get the RealScalar
//norm quaternion to generate the unit quaternion
namespace dcm {
namespace details {
enum Scalemode {
one,
two,
three,
multiple_inrange,
multiple_outrange
};
template<typename Sys>
struct ClusterMath : public boost::noncopyable {
public:
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef std::shared_ptr<Geometry3D> Geom;
typedef typename module3d::math_prop math_prop;
typedef typename module3d::fix_prop fix_prop;
typedef typename Kernel::number_type Scalar;
typename Kernel::Transform3D m_transform, m_ssrTransform, m_resetTransform;
typename Kernel::DiffTransform3D m_diffTrans;
typename Kernel::Vector3Map m_normQ;
typename Kernel::Quaternion m_resetQuaternion;
int m_offset, m_offset_rot;
bool init, fix;
std::vector<Geom> m_geometry;
typename Kernel::Vector3Map m_translation;
//shift scale stuff
typename Kernel::Vector3 midpoint, m_shift, scale_dir, maxm, minm, max, fixtrans;
Scalemode mode;
Scalar m_scale;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Vec m_points, m_pseudo;
#ifdef USE_LOGGING
src::logger log;
#endif
public:
ClusterMath();
void setParameterOffset(int offset, AccessType t);
int getParameterOffset(AccessType t);
typename Kernel::Vector3Map& getNormQuaternionMap();
typename Kernel::Vector3Map& getTranslationMap();
void initMaps();
void initFixMaps();
typename Kernel::Transform3D& getTransform();
typename Kernel::Transform3D::Translation const& getTranslation() const;
typename Kernel::Transform3D::Rotation const& getRotation() const;
void setTransform(typename Kernel::Transform3D const& t);
void setTranslation(typename Kernel::Transform3D::Translation const& );
void setRotation(typename Kernel::Transform3D::Rotation const&);
void mapsToTransform(typename Kernel::Transform3D& trans);
void transformToMaps(typename Kernel::Transform3D& trans);
void finishCalculation();
void finishFixCalculation();
void resetClusterRotation(typename Kernel::Transform3D& trans);
void calcDiffTransform(typename Kernel::DiffTransform3D& trans);
void recalculate();
void addGeometry(Geom g);
void clearGeometry();
std::vector<Geom>& getGeometry();
struct map_downstream {
details::ClusterMath<Sys>& m_clusterMath;
typename Kernel::Transform3D m_transform;
bool m_isFixed;
map_downstream(details::ClusterMath<Sys>& cm, bool fix);
void operator()(Geom g);
void operator()(std::shared_ptr<Cluster> c);
};
void mapClusterDownstreamGeometry(std::shared_ptr<Cluster> cluster);
//Calculate the scale of the cluster. Therefore the midpoint is calculated and the scale is
// defined as the max distance between the midpoint and the points.
Scalar calculateClusterScale();
void applyClusterScale(Scalar scale, bool isFixed);
private:
Scalar calcOnePoint(const typename Kernel::Vector3& p);
Scalar calcTwoPoints(const typename Kernel::Vector3& p1, const typename Kernel::Vector3& p2);
Scalar calcThreePoints(const typename Kernel::Vector3& p1,
const typename Kernel::Vector3& p2, const typename Kernel::Vector3& p3);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}//details
}//dcm
#ifndef DCM_EXTERNAL_3D
#include "imp/clustermath_imp.hpp"
#endif
#endif //GCM_CLUSTERMATH_H

View File

@@ -1,299 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_COINCIDENT_HPP
#define DCM_COINCIDENT_HPP
#include <opendcm/core/equations.hpp>
#include "distance.hpp"
namespace dcm {
namespace details {
//we need a custom orientation type to allow coincidents with points
struct ci_orientation : public Equation<ci_orientation, Direction, 4, rotation> {
using Equation::operator=;
using Equation::options;
ci_orientation() : Equation() {
setDefault();
};
ci_orientation& operator=(const ci_orientation& d) {
return Equation::assign(d);
};
void setDefault() {
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(103) << error_message("unsupported geometry in coincidence orientation constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
typename ci_orientation::options values;
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::point3D, tag::point3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typename ci_orientation::options values;
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.setZero();
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.setZero();
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::point3D, tag::line3D > : public ci_orientation::type< Kernel, tag::point3D, tag::point3D > {};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::point3D, tag::plane3D > : public ci_orientation::type< Kernel, tag::point3D, tag::point3D > {};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::point3D, tag::cylinder3D > : public ci_orientation::type< Kernel, tag::point3D, tag::point3D > {};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::line3D, tag::line3D > : public dcm::Orientation::type< Kernel, tag::line3D, tag::line3D > {
//we misuse the scale method to prevent an unallowed direction: perpendicular (and distance is not defined for it)
void setScale(typename Kernel::number_type scale) {
if(fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::line3D >::values).second == perpendicular)
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::line3D >::values).second = parallel;
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::line3D, tag::plane3D > : public dcm::Orientation::type< Kernel, tag::line3D, tag::plane3D > {
//we misuse the scale method to change whatever direction was set to the only valid one: perpendicular
void setScale(typename Kernel::number_type scale) {
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::plane3D >::values).second = perpendicular;
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::line3D, tag::cylinder3D > : public dcm::Orientation::type< Kernel, tag::line3D, tag::cylinder3D > {
//we misuse the scale method to prevent an unallowed direction: perpendicular (and distance is not defined for it)
void setScale(typename Kernel::number_type scale) {
if(fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::cylinder3D >::values).second == perpendicular)
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::line3D, tag::cylinder3D >::values).second = parallel;
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::plane3D, tag::plane3D > : public dcm::Orientation::type< Kernel, tag::plane3D, tag::plane3D > {
//we misuse the scale method to prevent an unallowed direction: perpendicular (and distance is not defined for it)
void setScale(typename Kernel::number_type scale) {
if(fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::plane3D, tag::plane3D >::values).second == perpendicular)
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::plane3D, tag::plane3D >::values).second = parallel;
};
};
template< typename Kernel >
struct ci_orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public dcm::Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > {
//we misuse the scale method to prevent an unallowed direction: perpendicular (and distance is not defined for it)
void setScale(typename Kernel::number_type scale) {
if(fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D >::values).second == perpendicular)
fusion::at_key<Direction>(dcm::Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D >::values).second = parallel;
};
};
//we need a custom distance type to use point-distance functions instead of real geometry distance
struct ci_distance : public Equation<ci_distance, mpl::vector2<double, SolutionSpace>, 5 > {
using Equation::operator=;
using Equation::options;
ci_distance() : Equation() {
setDefault();
};
ci_distance& operator=(const ci_distance& d) {
return Equation::assign(d);
};
void setDefault() {
fusion::at_key<double>(values) = std::make_pair(false, 0.);
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
type() {
throw constraint_error() << boost::errinfo_errno(104) << error_message("unsupported geometry in coincidence distance constraint")
<< error_type_first_geometry(typeid(Tag1).name()) << error_type_second_geometry(typeid(Tag2).name());
};
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
typename ci_distance::options values;
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::point3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::point3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::line3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::point3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::line3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::line3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::line3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::plane3D, tag::plane3D > : public dcm::Distance::type< Kernel, tag::plane3D, tag::plane3D > {};
template< typename Kernel >
struct ci_distance::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public dcm::Distance::type< Kernel, tag::point3D, tag::line3D > {};
}//details
struct Coincidence : public dcm::constraint_sequence< fusion::vector2< details::ci_distance, details::ci_orientation >, Coincidence > {
//allow to set the distance
Coincidence& operator()(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
Coincidence& operator=(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
};
//no standard equation, create our own object
static Coincidence coincidence;
}//dcm
#endif //DCM_COINCIDENT_HPP

View File

@@ -1,68 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DEFINES_3D_H
#define GCM_DEFINES_3D_H
namespace dcm {
enum SolverFailureHandling {
IgnoreResults,
ApplyResults
};
enum SubsystemSolveHandling {
Automatic,
Manual
};
//options
struct solverfailure {
typedef SolverFailureHandling type;
typedef setting_property kind;
struct default_value {
SolverFailureHandling operator()() {
return IgnoreResults;
};
};
};
struct subsystemsolving {
typedef SubsystemSolveHandling type;
typedef setting_property kind;
struct default_value {
SubsystemSolveHandling operator()() {
return Manual;
};
};
};
namespace details {
enum { cluster3D = 100};
struct m3d {}; //base of module3d::type to allow other modules check for it
}
}
#endif

View File

@@ -1,734 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DISTANCE3D_H
#define GCM_DISTANCE3D_H
#include "geometry.hpp"
#include <opendcm/core/constraint.hpp>
#include <opendcm/core/imp/kernel_imp.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/math/special_functions.hpp>
namespace dcm {
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::point3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar sc_value;
typename Distance::options values;
//template definition
void calculatePseudo(typename Kernel::Vector& param1, Vec& v1, typename Kernel::Vector& param2, Vec& v2) {};
void setScale(Scalar scale) {
sc_value = fusion::at_key<double>(values).second*scale;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return (param1-param2).norm() - sc_value;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return (param1-param2).dot(dparam1) / (param1-param2).norm();
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return (param1-param2).dot(-dparam2) / (param1-param2).norm();
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient = (param1-param2) / (param1-param2).norm();
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient = (param2-param1) / (param1-param2).norm();
};
};
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef typename Kernel::Vector3 Vector3;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar sc_value;
typename Distance::options values;
Vector3 diff, n, dist;
#ifdef USE_LOGGING
dcm_logger log;
attrs::mutable_constant< std::string > tag;
type() : tag("Distance point3D line3D") {
log.add_attribute("Tag", tag);
};
#endif
//template definition
void calculatePseudo(typename Kernel::Vector& point, Vec& v1, typename Kernel::Vector& line, Vec& v2) {
Vector3 pp = line.head(3) + (line.head(3)-point.head(3)).norm()*line.template segment<3>(3);
#ifdef USE_LOGGING
if(!boost::math::isnormal(pp.norm()))
BOOST_LOG_SEV(log, error) << "Unnormal pseudopoint detected";
#endif
v2.push_back(pp);
};
void setScale(Scalar scale) {
sc_value = fusion::at_key<double>(values).second*scale;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& point, const E::MatrixBase<DerivedB>& line) {
//diff = point1 - point2
n = line.template segment<3>(3);
diff = line.template head<3>() - point.template head<3>();
dist = diff - diff.dot(n)*n;
const Scalar res = dist.norm() - sc_value;
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal residual detected: "<<res;
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& line,
const E::MatrixBase<DerivedC>& dpoint) {
if(dist.norm() == 0)
return 1.;
const Vector3 d_diff = -dpoint.template head<3>();
const Vector3 d_dist = d_diff - d_diff.dot(n)*n;
const Scalar res = dist.dot(d_dist)/dist.norm();
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal first cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", line: "<<line.transpose()
<<" and dpoint: "<<dpoint.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& line,
const E::MatrixBase<DerivedC>& dline) {
if(dist.norm() == 0)
return 1.;
const Vector3 d_diff = dline.template head<3>();
const Vector3 d_n = dline.template segment<3>(3);
const Vector3 d_dist = d_diff - ((d_diff.dot(n)+diff.dot(d_n))*n + diff.dot(n)*d_n);
const Scalar res = dist.dot(d_dist)/dist.norm();
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal second cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", line: "<<line.transpose()
<< "and dline: "<<dline.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& line,
E::MatrixBase<DerivedC>& gradient) {
if(dist.norm() == 0) {
gradient.head(3).setOnes();
return;
}
const Vector3 res = (n*n.transpose())*dist - dist;
gradient.head(3) = res/dist.norm();
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& line,
E::MatrixBase<DerivedC>& gradient) {
if(dist.norm() == 0) {
gradient.head(6).setOnes();
return;
}
const Vector3 res = (-n*n.transpose())*dist + dist;
gradient.head(3) = res/dist.norm();
const Scalar mult = n.transpose()*dist;
gradient.template segment<3>(3) = -(mult*diff + diff.dot(n)*dist)/dist.norm();
};
};
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar sc_value, result;
SolutionSpace sspace;
typename Distance::options values;
#ifdef USE_LOGGING
src::logger log;
attrs::mutable_constant< std::string > tag;
type() : tag("Distance point3D plane3D") {
log.add_attribute("Tag", tag);
};
#endif
//template definition
void calculatePseudo(typename Kernel::Vector& param1, Vec& v1, typename Kernel::Vector& param2, Vec& v2) {
//typename Kernel::Vector3 pp = param1.head(3)- ((param1.head(3)-param2.head(3)).dot(param2.tail(3)) / param2.tail(3).norm()*(param2.tail(3)));
//v2.push_back(pp);
typename Kernel::Vector3 dir = (param1.template head<3>()-param2.template head<3>()).cross(param2.template segment<3>(3));
dir = param2.template segment<3>(3).cross(dir).normalized();
typename Kernel::Vector3 pp = param2.head(3) + (param1.head(3)-param2.head(3)).norm()*dir;
v2.push_back(pp);
#ifdef USE_LOGGING
if(!boost::math::isnormal(pp.norm()))
BOOST_LOG_SEV(log, error) << "Unnormal pseudopoint detected";
#endif
};
void setScale(Scalar scale) {
sc_value = fusion::at_key<double>(values).second*scale;
sspace = fusion::at_key<SolutionSpace>(values).second;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
//(p1-p2)°n / |n| - distance
result = (param1.head(3)-param2.head(3)).dot(param2.tail(3)) / param2.tail(3).norm();
if(sspace == bidirectional)
return std::abs(result) - sc_value;
if(sspace == positiv_directional)
return result - sc_value;
if(sspace == negative_directional)
return result + sc_value;
#ifdef USE_LOGGING
if(!boost::math::isfinite(result))
BOOST_LOG_SEV(log, error) << "Unnormal residual detected: " << result;
#endif
return result;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
//dp1°n / |n|
//if(dparam1.norm()!=1) return 0;
const Scalar res = (dparam1.head(3)).dot(param2.tail(3)) / param2.tail(3).norm();
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal first cluster gradient detected: "<<res;
#endif
//r = sqrt(x^2) = (x^2)^(1/2)
//r' = 1/2(x^2)^(-1/2) * (x^2)'
//r' = 1/sqrt(x^2) * x * x'
//r' = sign(x)*x'
if(sspace == bidirectional && result<0.)
return -res;
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
const typename Kernel::Vector3 p1 = param1.head(3);
const typename Kernel::Vector3 p2 = param2.head(3);
const typename Kernel::Vector3 dp2 = dparam2.head(3);
const typename Kernel::Vector3 n = param2.tail(3);
const typename Kernel::Vector3 dn = dparam2.tail(3);
//if(dparam2.norm()!=1) return 0;
const Scalar res = (((-dp2).dot(n) + (p1-p2).dot(dn)) / n.norm() - (p1-p2).dot(n)* n.dot(dn)/std::pow(n.norm(),3));
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal second cluster gradient detected: "<<res;
#endif
if(sspace == bidirectional && result<0.)
return -res;
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient = param2.tail(3) / param2.tail(3).norm();
if(sspace == bidirectional && result<0.)
gradient *= -1.;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
const typename Kernel::Vector3 p1m2 = param1.head(3) - param2.head(3);
const typename Kernel::Vector3 n = param2.tail(3);
gradient.head(3) = -n / n.norm();
gradient.tail(3) = (p1m2)/n.norm() - (p1m2).dot(n)*n/std::pow(n.norm(),3);
if(sspace == bidirectional && result<0.)
gradient *= -1.;
};
};
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance::type< Kernel, tag::point3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
Scalar result;
SolutionSpace sspace;
using Distance::template type<Kernel, tag::point3D, tag::line3D>::sc_value;
using Distance::template type<Kernel, tag::point3D, tag::line3D>::values;
#ifdef USE_LOGGING
type() {
Distance::template type< Kernel, tag::point3D, tag::line3D >::tag.set("Distance point3D cylinder3D");
};
#endif
void setScale(Scalar scale) {
Distance::template type<Kernel, tag::point3D, tag::line3D>::setScale(scale);
sspace = fusion::at_key<SolutionSpace>(values).second;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
//(p1-p2)°n / |n| - distance
result = Distance::type< Kernel, tag::point3D, tag::line3D >::calculate(param1, param2) - param2(6);
if(sspace==negative_directional || (sspace == bidirectional && (result+sc_value)<0.))
return result+2*sc_value;
return result;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientFirst(param1,param2,dparam1);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientSecond(param1,param2,dparam2) - dparam2(6);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientFirstComplete(param1,param2,gradient);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientSecondComplete(p1,p2,g);
g(6) = -1;
};
};
//TODO: this won't work for parallel lines. switch to point-line distance when lines are parallel
template<typename Kernel>
struct Distance::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef typename Kernel::Vector3 Vector3;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar sc_value, cdn, nxn_n;
typename Distance::options values;
Vector3 c, n1, n2, nxn;
//if the lines are parallel we need to fall back to point-line distance
//to do this efficiently we just hold a point-line distance equation and use it instead
Distance::type<Kernel, tag::point3D, tag::line3D> pl_eqn;
#ifdef USE_LOGGING
src::logger log;
attrs::mutable_constant< std::string > tag;
type() : tag("Distance line3D line3D") {
log.add_attribute("Tag", tag);
};
#endif
//template definition
void calculatePseudo(typename Kernel::Vector& line1, Vec& v1, typename Kernel::Vector& line2, Vec& v2) {
//add the line points of shortest distance as pseudopoints
const Vector3 c = line2.template head<3>() - line1.template head<3>();
const Vector3 n1 = line1.template segment<3>(3);
const Vector3 n2 = line2.template segment<3>(3);
const Vector3 nxn = n1.cross(n2);
//parallel lines are treated as point line
if(Kernel::isSame(nxn.norm(), 0, 1e-6)) {
pl_eqn.calculatePseudo(line1, v1, line2, v2);
return;
};
const Vector3 r = c.cross(nxn)/nxn.squaredNorm();
Vector3 pp1 = line1.template head<3>() + r.dot(n2)*n1;
Vector3 pp2 = line2.template head<3>() + r.dot(n1)*n2;
#ifdef USE_LOGGING
if(!boost::math::isfinite(pp1.norm()) || !boost::math::isfinite(pp2.norm()))
BOOST_LOG_SEV(log, error) << "Unnormal pseudopoint detected";
#endif
v1.push_back(pp1);
v2.push_back(pp2);
};
void setScale(Scalar scale) {
sc_value = fusion::at_key<double>(values).second*scale;
fusion::copy(values, pl_eqn.values);
pl_eqn.setScale(scale);
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& line1, const E::MatrixBase<DerivedB>& line2) {
//diff = point1 - point2
n1 = line1.template segment<3>(3);
n2 = line2.template segment<3>(3);
nxn = n1.cross(n2);
nxn_n = nxn.norm();
if(Kernel::isSame(nxn_n, 0, 1e-6))
return pl_eqn.calculate(line1, line2);
c = line2.template head<3>() - line1.template head<3>();
cdn = c.dot(nxn);
const Scalar res = std::abs(cdn) / nxn.norm();
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal residual detected: "<<res;
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& line1,
const E::MatrixBase<DerivedB>& line2,
const E::MatrixBase<DerivedC>& dline1) {
if(Kernel::isSame(nxn_n, 0, 1e-6))
return pl_eqn.calculateGradientFirst(line1, line2, dline1);
const Vector3 nxn_diff = dline1.template segment<3>(3).cross(n2);
Scalar diff = (-dline1.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn_n;
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn_n;
//absolute value requires different differentation for different results
if(cdn <= 0)
diff *= -1;
diff /= std::pow(nxn_n,2);
#ifdef USE_LOGGING
if(!boost::math::isfinite(diff))
BOOST_LOG_SEV(log, error) << "Unnormal first cluster gradient detected: "<<diff
<<" with line1: "<<line1.transpose()<<", line2: "<<line2.transpose()
<<" and dline1: "<<dline1.transpose();
#endif
return diff;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& line1,
const E::MatrixBase<DerivedB>& line2,
const E::MatrixBase<DerivedC>& dline2) {
if(Kernel::isSame(nxn_n, 0, 1e-6))
return pl_eqn.calculateGradientSecond(line1, line2, dline2);
const Vector3 nxn_diff = n1.cross(dline2.template segment<3>(3));
Scalar diff = (dline2.template head<3>().dot(nxn)+c.dot(nxn_diff))*nxn_n;
diff -= c.dot(nxn)*nxn.dot(nxn_diff)/nxn_n;
//absolute value requires different differentation for different results
if(cdn <= 0)
diff *= -1;
diff /= std::pow(nxn_n,2);
#ifdef USE_LOGGING
if(!boost::math::isfinite(diff))
BOOST_LOG_SEV(log, error) << "Unnormal first cluster gradient detected: "<<diff
<<" with line1: "<<line1.transpose()<<", line2: "<<line2.transpose()
<<" and dline2: "<<dline2.transpose();
#endif
return diff;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& line1,
const E::MatrixBase<DerivedB>& line2,
E::MatrixBase<DerivedC>& gradient) {
if(Kernel::isSame(nxn_n, 0, 1e-6)) {
pl_eqn.calculateGradientFirstComplete(line1, line2, gradient);
return;
}
if(cdn >= 0) {
gradient.template head<3>() = -nxn/nxn_n;
gradient.template segment<3>(3) = (c.cross(-n2)*nxn_n-c.dot(nxn)*n2.cross(nxn)/nxn_n)/std::pow(nxn_n,2);
}
else {
gradient.template head<3>() = nxn/nxn_n;
gradient.template segment<3>(3) = (-c.cross(-n2)*nxn_n+c.dot(nxn)*n2.cross(nxn)/nxn_n)/std::pow(nxn_n,2);
}
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& line1,
const E::MatrixBase<DerivedB>& line2,
E::MatrixBase<DerivedC>& gradient) {
if(Kernel::isSame(nxn_n, 0, 1e-6)) {
pl_eqn.calculateGradientFirstComplete(line1, line2, gradient);
return;
}
if(cdn >= 0) {
gradient.template head<3>() = nxn/nxn_n;
gradient.template segment<3>(3) = (c.cross(n1)*nxn_n-c.dot(nxn)*((-n1).cross(nxn))/nxn_n)/std::pow(nxn_n,2);
}
else {
gradient.template head<3>() = -nxn/nxn_n;
gradient.template segment<3>(3) = (-c.cross(n1)*nxn_n+c.dot(nxn)*((-n1).cross(nxn))/nxn_n)/std::pow(nxn_n,2);
}
};
};
//only defined when line and plane are parallel, therefore it's the same as the point-plane distance
template<typename Kernel>
struct Distance::type< Kernel, tag::line3D, tag::plane3D > : public Distance::type< Kernel, tag::point3D, tag::plane3D > {
#ifdef USE_LOGGING
type() : Distance::type< Kernel, tag::point3D, tag::plane3D >() {
Distance::type< Kernel, tag::point3D, tag::plane3D >::tag.set("Distance line3D plane3D");
};
#endif
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,grad);
g.segment(3,3).setZero();
};
};
template<typename Kernel>
struct Distance::type< Kernel, tag::line3D, tag::cylinder3D > : public Distance::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
using Distance::type< Kernel, tag::line3D, tag::line3D >::sc_value;
Scalar result;
SolutionSpace sspace;
#ifdef USE_LOGGING
type() : Distance::type< Kernel, tag::line3D, tag::line3D >() {
Distance::type< Kernel, tag::line3D, tag::line3D >::tag.set("Distance line3D cylinder3D");
};
#endif
void setScale(Scalar scale) {
Distance::type< Kernel, tag::line3D, tag::line3D >::setScale(scale);
sspace = fusion::at_key<SolutionSpace>(Distance::type< Kernel, tag::line3D, tag::line3D >::values).second;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
//(p1-p2)°n / |n| - distance
result = Distance::type< Kernel, tag::line3D, tag::line3D >::calculate(param1, param2) - param2(6);
//for parallel line and cylinder we may use the solution space methods
if(Kernel::isSame(Distance::type< Kernel, tag::line3D, tag::line3D >::nxn_n, 0, 1e-6) &&
(sspace==negative_directional || (sspace == bidirectional && (result+sc_value)<0.)))
return result+2*sc_value;
return result;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
Distance::type< Kernel, tag::line3D, tag::line3D >::calculateGradientSecondComplete(p1,p2,g);
g(6) = -1;
};
};
//only defined when planes are parallel, therefore it's the same as the point-plane distance
template<typename Kernel>
struct Distance::type< Kernel, tag::plane3D, tag::plane3D > : public Distance::type< Kernel, tag::point3D, tag::plane3D > {
#ifdef USE_LOGGING
type() : Distance::type< Kernel, tag::point3D, tag::plane3D >() {
Distance::type< Kernel, tag::point3D, tag::plane3D >::tag.set("Distance plane3D plane3D");
};
#endif
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p1,p2,grad);
g.segment(3,3).setZero();
};
};
//only defined when plane and cylinder are parallel, therefore it's the same as the point-plane distance
template<typename Kernel>
struct Distance::type< Kernel, tag::plane3D, tag::cylinder3D > : public Distance::type< Kernel, tag::point3D, tag::plane3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
#ifdef USE_LOGGING
type() : Distance::type< Kernel, tag::point3D, tag::plane3D >() {
Distance::type< Kernel, tag::point3D, tag::plane3D >::tag.set("Distance plane3D cylinder3D");
};
#endif
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
//(p1-p2)°n / |n| - distance
const Scalar res = Distance::type< Kernel, tag::point3D, tag::plane3D >::calculate(param2, param1);
if(Distance::type< Kernel, tag::point3D, tag::plane3D >::sspace == negative_directional)
return res + param2(6);
return res - param2(6);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
const E::MatrixBase<DerivedC>& dp1) {
return Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientSecond(p2,p1,dp1);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
const E::MatrixBase<DerivedC>& dp2) {
return Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirst(p2,p1,dp2);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientSecondComplete(p2,p1,g);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p2,p1,grad);
g.segment(3,3).setZero();
if(Distance::type< Kernel, tag::point3D, tag::plane3D >::sspace == negative_directional)
g(6) = 1;
else
g(6) = -1;
};
};
template<typename Kernel>
struct Distance::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public Distance::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
#ifdef USE_LOGGING
type() : Distance::type< Kernel, tag::line3D, tag::line3D >() {
Distance::type< Kernel, tag::line3D, tag::line3D >::tag.set("Distance cylinder3D cylinder3D");
};
#endif
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
//(p1-p2)°n / |n| - distance
const Scalar res = Distance::type< Kernel, tag::line3D, tag::line3D >::calculate(param1, param2);
return res - param1(6) - param2(6);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
Distance::type< Kernel, tag::line3D, tag::line3D >::calculateGradientFirstComplete(p1,p2,g);
g(6) = -1;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& p1,
const E::MatrixBase<DerivedB>& p2,
E::MatrixBase<DerivedC>& g) {
Distance::type< Kernel, tag::line3D, tag::line3D >::calculateGradientSecondComplete(p1,p2,g);
g(6) = -1;
};
};
}//namespace dcm
#endif //GCM_DISTANCE3D_H

View File

@@ -1,133 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DOF_H
#define GCM_DOF_H
#include <utility>
#include <vector>
namespace dcm {
enum remaining {
nothing = 0,
line,
plane,
volume
};
template<typename K, typename C>
class Dof {
typedef typename K::Vector3 Vec;
typedef std::pair<Vec, C> VecID;
public:
typedef std::vector<C> ConstraintVector;
typedef std::pair<bool, ConstraintVector> Result;
Dof() : m_translation(volume), m_rotation(volume) {};
int dofTranslational() {
return m_translation;
};
int dofRotational() {
return m_rotation;
};
int dof() {
return dofTranslational() + dofRotational();
};
Result removeTranslationDirection(Vec& v, C constraint) {
if(m_translation == nothing) {
ConstraintVector cv;
cv.push_back(tp1.second);
cv.push_back(tp2.second);
cv.push_back(tp3.second);
return std::make_pair(false,cv);
} else if(m_translation == volume) {
m_translation = plane;
tp1 = std::make_pair(v, constraint);
} else if(m_translation == plane) {
if(K::isSame(tp1.first, v, 1e-6) || K::isOpposite(tp1.first, v, 1e-6)) {
ConstraintVector cv;
cv.push_back(tp1.second);
return std::make_pair(false,cv);
}
m_translation = line;
tp2 = std::make_pair(v, constraint);
} else if(m_translation == line) {
if(tp1.first.cross(tp2.first).dot(v) < 0.001) {
ConstraintVector cv;
cv.push_back(tp1.second);
cv.push_back(tp2.second);
return std::make_pair(false,cv);
}
m_translation = nothing;
tp3 = std::make_pair(v, constraint);
}
return std::make_pair(true, ConstraintVector());
};
Result allowOnlyRotationDirection(Vec& v, C constraint) {
if(m_rotation == nothing) {
ConstraintVector cv;
cv.push_back(rp1.second);
cv.push_back(rp2.second);
return std::make_pair(false, cv);
} else if(m_rotation == volume) {
m_rotation = line;
rp1 = std::make_pair(v, constraint);
} else if(m_rotation == plane) {
return std::make_pair(false, ConstraintVector()); //error as every function call removes 2 dof's
} else if(m_rotation == line) {
if(K::isSame(rp1.first, v, 1e-6) || K::isOpposite(rp1.first, v, 1e-6)) {
ConstraintVector cv;
cv.push_back(rp1.second);
return std::make_pair(false, cv);
}
m_rotation = nothing;
rp2 = std::make_pair(v, constraint);
}
return std::make_pair(true, ConstraintVector());
};
private:
int m_translation, m_rotation;
VecID tp1,tp2,tp3; //translation pairs
VecID rp1, rp2; //rotation pairs
};
}
#endif //GCM_DOF_H

View File

@@ -1,158 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GEOMETRY_3D_H
#define GCM_GEOMETRY_3D_H
#include <opendcm/core/geometry.hpp>
namespace dcm {
namespace tag {
struct point3D : details::basic_geometry<weight::point, 3, true, true> {};
struct direction3D : details::basic_geometry<weight::direction, 3, true, false> {};
struct line3D : details::stacked2_geometry<weight::line, point3D, direction3D> {};
struct plane3D : details::stacked2_geometry<weight::plane, point3D, direction3D> {};
struct cylinder3D : details::stacked3_geometry<weight::cylinder, point3D, direction3D, parameter> {};
} //tag
namespace modell {
struct XYZ {
/*Modell XYZ:
* 0 = X;
* 1 = Y;
* 2 = Z;
*/
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void extract(Type& t, Vector& v) {
Accessor a;
v(0) = a.template get<Scalar, 0>(t);
v(1) = a.template get<Scalar, 1>(t);
v(2) = a.template get<Scalar, 2>(t);
}
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void inject(Type& t, Vector& v) {
Accessor a;
a.template set<Scalar, 0>(v(0), t);
a.template set<Scalar, 1>(v(1), t);
a.template set<Scalar, 2>(v(2), t);
a.finalize(t);
};
};
struct XYZ2 {
/*Modell XYZ2: two xyz parts after each other
* 0 = X;
* 1 = Y;
* 2 = Z;
* 3 = X dir;
* 4 = Y dir;
* 5 = Z dir;
*/
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void extract(Type& t, Vector& v) {
Accessor a;
v(0) = a.template get<Scalar, 0>(t);
v(1) = a.template get<Scalar, 1>(t);
v(2) = a.template get<Scalar, 2>(t);
v(3) = a.template get<Scalar, 3>(t);
v(4) = a.template get<Scalar, 4>(t);
v(5) = a.template get<Scalar, 5>(t);
}
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void inject(Type& t, Vector& v) {
Accessor a;
a.template set<Scalar, 0>(v(0), t);
a.template set<Scalar, 1>(v(1), t);
a.template set<Scalar, 2>(v(2), t);
a.template set<Scalar, 3>(v(3), t);
a.template set<Scalar, 4>(v(4), t);
a.template set<Scalar, 5>(v(5), t);
a.finalize(t);
};
};
struct XYZ2P {
/*Modell XYZ2P: two xyz parts after each other and one parameter
* 0 = X;
* 1 = Y;
* 2 = Z;
* 3 = X dir;
* 4 = Y dir;
* 5 = Z dir;
* 6 = Parameter
*/
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void extract(Type& t, Vector& v) {
Accessor a;
v(0) = a.template get<Scalar, 0>(t);
v(1) = a.template get<Scalar, 1>(t);
v(2) = a.template get<Scalar, 2>(t);
v(3) = a.template get<Scalar, 3>(t);
v(4) = a.template get<Scalar, 4>(t);
v(5) = a.template get<Scalar, 5>(t);
v(6) = a.template get<Scalar, 6>(t);
}
template<typename Scalar, typename Accessor, typename Vector, typename Type>
void inject(Type& t, Vector& v) {
Accessor a;
a.template set<Scalar, 0>(v(0), t);
a.template set<Scalar, 1>(v(1), t);
a.template set<Scalar, 2>(v(2), t);
a.template set<Scalar, 3>(v(3), t);
a.template set<Scalar, 4>(v(4), t);
a.template set<Scalar, 5>(v(5), t);
a.template set<Scalar, 6>(v(6), t);
a.finalize(t);
};
};
}
//dummy accessor
struct dummy_accessor {
template<typename Scalar, int ID, typename T>
Scalar get(T& t) {
return 1;
};
template<typename Scalar, int ID, typename T>
void set(Scalar value, T& t) {
//TODO: throw
};
template<typename T>
void finalize(T& t) {};
};
//dummy geometry traits for boost blank, will never be used
template<>
struct geometry_traits<boost::blank> {
typedef tag::direction3D tag;
typedef modell::XYZ modell;
typedef dummy_accessor accessor;
};
}
#endif //GCM_GEOMETRY_3D_H

View File

@@ -1,698 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CLUSTERMATH_IMP_H
#define DCM_CLUSTERMATH_IMP_H
#include "../clustermath.hpp"
#ifdef DCM_EXTERNAL_CORE
#include "opendcm/core/imp/transformation_imp.hpp"
#endif
//include it here as it is in the same external compilation unit as clustermath
#include "solver_imp.hpp"
namespace dcm {
namespace details {
template<typename Sys>
ClusterMath<Sys>::ClusterMath() : m_normQ(NULL), m_translation(NULL), init(false) {
m_resetTransform = Eigen::AngleAxisd(M_PI*2./3., Eigen::Vector3d(1,1,1).normalized());
m_shift.setZero();
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Clustermath3D"));
#endif
};
template<typename Sys>
void ClusterMath<Sys>::setParameterOffset(int offset, dcm::AccessType t) {
if(t == general)
m_offset = offset;
else
m_offset_rot = offset;
};
template<typename Sys>
int ClusterMath<Sys>::getParameterOffset(AccessType t) {
if(t == general)
return m_offset;
else
return m_offset_rot;
};
template<typename Sys>
typename ClusterMath<Sys>::Kernel::Vector3Map& ClusterMath<Sys>::getNormQuaternionMap() {
return m_normQ;
};
template<typename Sys>
typename ClusterMath<Sys>::Kernel::Vector3Map& ClusterMath<Sys>::getTranslationMap() {
return m_translation;
};
template<typename Sys>
void ClusterMath<Sys>::initMaps() {
transformToMaps(m_transform);
init = true;
midpoint.setZero();
m_shift.setZero();
m_ssrTransform.setIdentity();
m_diffTrans = m_transform;
fix=false;
#ifdef USE_LOGGING
BOOST_LOG(log) << "Init transform: "<<m_transform;
#endif
};
template<typename Sys>
void ClusterMath<Sys>::initFixMaps() {
//when fixed no maps exist
new(&m_translation) typename Kernel::Vector3Map(&fixtrans(0));
m_translation = m_transform.translation().vector();
init = true;
midpoint.setZero();
m_shift.setZero();
m_ssrTransform.setIdentity();
m_diffTrans = m_transform;
fix=true;
#ifdef USE_LOGGING
BOOST_LOG(log) << "Init fix transform: "<<m_transform;
#endif
};
template<typename Sys>
typename ClusterMath<Sys>::Kernel::Transform3D& ClusterMath<Sys>::getTransform() {
return m_transform;
};
template<typename Sys>
typename ClusterMath<Sys>::Kernel::Transform3D::Translation const& ClusterMath<Sys>::getTranslation() const {
return m_transform.translation();
};
template<typename Sys>
typename ClusterMath<Sys>::Kernel::Transform3D::Rotation const& ClusterMath<Sys>::getRotation() const {
return m_transform.rotation();
};
template<typename Sys>
void ClusterMath<Sys>::setTransform(typename ClusterMath<Sys>::Kernel::Transform3D const& t) {
m_transform = t;
};
template<typename Sys>
void ClusterMath<Sys>::setTranslation(typename ClusterMath<Sys>::Kernel::Transform3D::Translation const& t) {
m_transform.setTranslation(t);
};
template<typename Sys>
void ClusterMath<Sys>::setRotation(typename ClusterMath<Sys>::Kernel::Transform3D::Rotation const& r) {
m_transform.setRotation(r);
};
template<typename Sys>
void ClusterMath<Sys>::mapsToTransform(typename ClusterMath<Sys>::Kernel::Transform3D& trans) {
//add scale only after possible reset
typename Kernel::Transform3D::Scaling scale(m_transform.scaling());
trans = m_diffTrans;
trans *= scale;
};
template<typename Sys>
void ClusterMath<Sys>::transformToMaps(typename ClusterMath<Sys>::Kernel::Transform3D& trans) {
const typename Kernel::Quaternion& m_quaternion = trans.rotation();
if(m_quaternion.w() < 1.) {
Scalar s = std::acos(m_quaternion.w())/std::sin(std::acos(m_quaternion.w()));
m_normQ = m_quaternion.vec()*s;
m_normQ /= NQFAKTOR;
} else {
m_normQ.setZero();
}
m_translation = trans.translation().vector();
};
template<typename Sys>
void ClusterMath<Sys>::finishCalculation() {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Finish calculation";
#endif
mapsToTransform(m_transform);
init=false;
m_transform = m_ssrTransform*m_transform;
//scale all geometries back to the original size
m_diffTrans *= typename Kernel::Transform3D::Scaling(1./m_ssrTransform.scaling().factor());
typedef typename std::vector<Geom>::iterator iter;
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++)
(*it)->recalculate(m_diffTrans);
#ifdef USE_LOGGING
BOOST_LOG(log) << "Finish transform:"<<std::endl<<m_transform;
#endif
};
template<typename Sys>
void ClusterMath<Sys>::finishFixCalculation() {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Finish fix calculation";
#endif
typedef typename std::vector<Geom>::iterator iter;
m_transform *= m_ssrTransform.inverse();
typename Kernel::DiffTransform3D diff(m_transform);
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++)
(*it)->recalculate(diff);
#ifdef USE_LOGGING
BOOST_LOG(log) << "Finish fix transform:"<<std::endl<<m_transform;
#endif
};
template<typename Sys>
void ClusterMath<Sys>::resetClusterRotation(typename ClusterMath<Sys>::Kernel::Transform3D& trans) {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Reset cluster rotation:"<<std::endl<<m_diffTrans;
#endif
trans = m_resetTransform.inverse()*trans;
m_ssrTransform *= m_resetTransform;
//m_transform = m_resetTransform.inverse()*m_transform;
//apply the needed transformation to all geometries local values
typedef typename std::vector<Geom>::iterator iter;
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++) {
(*it)->transform(m_resetTransform);
};
};
template<typename Sys>
void ClusterMath<Sys>::calcDiffTransform(typename ClusterMath<Sys>::Kernel::DiffTransform3D& trans) {
Scalar norm = m_normQ.norm();
trans.setIdentity();
if(norm < 0.1) {
if(norm == 0) {
trans *= typename Kernel::Transform3D::Translation(m_translation);
resetClusterRotation(trans);
} else {
const Scalar fac = std::sin(NQFAKTOR*norm)/norm;
trans = typename Kernel::Quaternion(std::cos(NQFAKTOR*norm), m_normQ(0)*fac, m_normQ(1)*fac,m_normQ(2)*fac);
trans *= typename Kernel::Transform3D::Translation(m_translation);
resetClusterRotation(trans);
}
transformToMaps(trans);
return;
}
const Scalar fac = std::sin(NQFAKTOR*norm)/norm;
trans = typename Kernel::Quaternion(std::cos(NQFAKTOR*norm), m_normQ(0)*fac, m_normQ(1)*fac, m_normQ(2)*fac);
trans *= typename Kernel::Transform3D::Translation(m_translation);
};
template<typename Sys>
void ClusterMath<Sys>::recalculate() {
calcDiffTransform(m_diffTrans);
const typename Kernel::Quaternion Q = m_diffTrans.rotation();
// now calculate the gradient quaternions and calculate the diff rotation matrices
// m_normQ = (a,b,c)
// n = ||m_normQ||
//
// Q = (a/n sin(n), b/n sin(n), c/n sin(n), cos(n))
//
//n=||m_normQ||, sn = sin(n)/n, sn3 = sin(n)/n^3, cn = cos(n)/n, divn = 1/n;
const Scalar n = m_normQ.norm();
const Scalar sn = std::sin(NQFAKTOR*n)/n;
const Scalar mul = (NQFAKTOR*std::cos(NQFAKTOR*n)-sn)/std::pow(n,2);
//dxa = dQx/da
const Scalar dxa = sn + std::pow(m_normQ(0),2)*mul;
const Scalar dxb = m_normQ(0)*m_normQ(1)*mul;
const Scalar dxc = m_normQ(0)*m_normQ(2)*mul;
const Scalar dya = m_normQ(1)*m_normQ(0)*mul;
const Scalar dyb = sn + std::pow(m_normQ(1),2)*mul;
const Scalar dyc = m_normQ(1)*m_normQ(2)*mul;
const Scalar dza = m_normQ(2)*m_normQ(0)*mul;
const Scalar dzb = m_normQ(2)*m_normQ(1)*mul;
const Scalar dzc = sn + std::pow(m_normQ(2),2)*mul;
const Scalar dwa = -sn*NQFAKTOR*m_normQ(0);
const Scalar dwb = -sn*NQFAKTOR*m_normQ(1);
const Scalar dwc = -sn*NQFAKTOR*m_normQ(2);
//write in the diffrot matrix, starting with dQ/dx
m_diffTrans.at(0,0) = -4.0*(Q.y()*dya+Q.z()*dza);
m_diffTrans.at(0,1) = -2.0*(Q.w()*dza+dwa*Q.z())+2.0*(Q.x()*dya+dxa*Q.y());
m_diffTrans.at(0,2) = 2.0*(dwa*Q.y()+Q.w()*dya)+2.0*(dxa*Q.z()+Q.x()*dza);
m_diffTrans.at(1,0) = 2.0*(Q.w()*dza+dwa*Q.z())+2.0*(Q.x()*dya+dxa*Q.y());
m_diffTrans.at(1,1) = -4.0*(Q.x()*dxa+Q.z()*dza);
m_diffTrans.at(1,2) = -2.0*(dwa*Q.x()+Q.w()*dxa)+2.0*(dya*Q.z()+Q.y()*dza);
m_diffTrans.at(2,0) = -2.0*(dwa*Q.y()+Q.w()*dya)+2.0*(dxa*Q.z()+Q.x()*dza);
m_diffTrans.at(2,1) = 2.0*(dwa*Q.x()+Q.w()*dxa)+2.0*(dya*Q.z()+Q.y()*dza);
m_diffTrans.at(2,2) = -4.0*(Q.x()*dxa+Q.y()*dya);
//dQ/dy
m_diffTrans.at(0,3) = -4.0*(Q.y()*dyb+Q.z()*dzb);
m_diffTrans.at(0,4) = -2.0*(Q.w()*dzb+dwb*Q.z())+2.0*(Q.x()*dyb+dxb*Q.y());
m_diffTrans.at(0,5) = 2.0*(dwb*Q.y()+Q.w()*dyb)+2.0*(dxb*Q.z()+Q.x()*dzb);
m_diffTrans.at(1,3) = 2.0*(Q.w()*dzb+dwb*Q.z())+2.0*(Q.x()*dyb+dxb*Q.y());
m_diffTrans.at(1,4) = -4.0*(Q.x()*dxb+Q.z()*dzb);
m_diffTrans.at(1,5) = -2.0*(dwb*Q.x()+Q.w()*dxb)+2.0*(dyb*Q.z()+Q.y()*dzb);
m_diffTrans.at(2,3) = -2.0*(dwb*Q.y()+Q.w()*dyb)+2.0*(dxb*Q.z()+Q.x()*dzb);
m_diffTrans.at(2,4) = 2.0*(dwb*Q.x()+Q.w()*dxb)+2.0*(dyb*Q.z()+Q.y()*dzb);
m_diffTrans.at(2,5) = -4.0*(Q.x()*dxb+Q.y()*dyb);
//dQ/dz
m_diffTrans.at(0,6) = -4.0*(Q.y()*dyc+Q.z()*dzc);
m_diffTrans.at(0,7) = -2.0*(Q.w()*dzc+dwc*Q.z())+2.0*(Q.x()*dyc+dxc*Q.y());
m_diffTrans.at(0,8) = 2.0*(dwc*Q.y()+Q.w()*dyc)+2.0*(dxc*Q.z()+Q.x()*dzc);
m_diffTrans.at(1,6) = 2.0*(Q.w()*dzc+dwc*Q.z())+2.0*(Q.x()*dyc+dxc*Q.y());
m_diffTrans.at(1,7) = -4.0*(Q.x()*dxc+Q.z()*dzc);
m_diffTrans.at(1,8) = -2.0*(dwc*Q.x()+Q.w()*dxc)+2.0*(dyc*Q.z()+Q.y()*dzc);
m_diffTrans.at(2,6) = -2.0*(dwc*Q.y()+Q.w()*dyc)+2.0*(dxc*Q.z()+Q.x()*dzc);
m_diffTrans.at(2,7) = 2.0*(dwc*Q.x()+Q.w()*dxc)+2.0*(dyc*Q.z()+Q.y()*dzc);
m_diffTrans.at(2,8) = -4.0*(Q.x()*dxc+Q.y()*dyc);
//recalculate all geometries
typedef typename std::vector<Geom>::iterator iter;
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++)
(*it)->recalculate(m_diffTrans);
};
template<typename Sys>
void ClusterMath<Sys>::addGeometry(Geom g) {
m_geometry.push_back(g);
};
template<typename Sys>
void ClusterMath<Sys>::clearGeometry() {
m_geometry.clear();
};
template<typename Sys>
std::vector<typename ClusterMath<Sys>::Geom>& ClusterMath<Sys>::getGeometry() {
return m_geometry;
};
template<typename Sys>
ClusterMath<Sys>::map_downstream::map_downstream(details::ClusterMath<Sys>& cm, bool fix)
: m_clusterMath(cm), m_isFixed(fix) {
m_transform = m_clusterMath.getTransform().inverse();
};
template<typename Sys>
void ClusterMath<Sys>::map_downstream::operator()(Geom g) {
//allow iteration over all mapped geometries
m_clusterMath.addGeometry(g);
//set the offsets so that geometry knows where it is in the parameter map
g->m_offset = m_clusterMath.getParameterOffset(general);
g->m_offset_rot = m_clusterMath.getParameterOffset(rotation);
//position and offset of the parameters must be set to the clusters values
g->setClusterMode(true, m_isFixed);
//calculate the appropriate local values
g->transform(m_transform);
};
template<typename Sys>
void ClusterMath<Sys>::map_downstream::operator()(std::shared_ptr<Cluster> c) {
//we transform the GLOBAL geometries to local ones in the subcluster! therefore
//we are not interested in the successive transformations, we only transform the
//global geometries with the cluster transform we want them to be local in, and that's
//the one supplied in the constructor
//m_transform *= c->template getClusterProperty<math_prop>().getTransform().inverse();
};
template<typename Sys>
void ClusterMath<Sys>::mapClusterDownstreamGeometry(std::shared_ptr<Cluster> cluster) {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Map downstream geometry";
#endif
map_downstream down(cluster->template getProperty<math_prop>(),
cluster->template getProperty<fix_prop>());
cluster->template for_each<Geometry3D>(down, true);
//TODO: if one subcluster is fixed the hole cluster should be too, as there are no
// dof's remaining between parts and so nothing can be moved when one part is fixed.
};
template<typename Sys>
typename ClusterMath<Sys>::Scalar ClusterMath<Sys>::calculateClusterScale() {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Calculate cluster scale with transform scale: "<<m_transform.scaling().factor();
#endif
//ensure the usage of the right transformation
if(!fix)
mapsToTransform(m_transform);
#ifdef USE_LOGGING
BOOST_LOG(log) << "Calculate cluster scale sec transform scale: "<<m_transform.scaling().factor();
#endif
//collect all points together
m_points.clear();
typename Kernel::Transform3D trans(m_transform.rotation(), m_transform.translation());
trans.invert();
typedef typename Vec::iterator iter;
for(iter it = m_pseudo.begin(); it != m_pseudo.end(); it++) {
m_points.push_back(trans*(*it));
}
typedef typename std::vector<Geom>::iterator g_iter;
for(g_iter it = m_geometry.begin(); it != m_geometry.end(); it++)
m_points.push_back((*it)->getPoint());
//start scale calculation
if(m_points.empty()) return 1.;
else if(m_points.size() == 1) {
const typename Kernel::Vector3 p = m_points[0];
return calcOnePoint(p);
} else if(m_points.size() == 2) {
const typename Kernel::Vector3 p1 = m_points[0];
const typename Kernel::Vector3 p2 = m_points[1];
if(Kernel::isSame((p1-p2).norm(), 0., 1e-10))
return calcOnePoint(p1);
return calcTwoPoints(p1, p2);
} else if(m_points.size() == 3) {
const typename Kernel::Vector3 p1 = m_points[0];
const typename Kernel::Vector3 p2 = m_points[1];
const typename Kernel::Vector3 p3 = m_points[2];
const typename Kernel::Vector3 d = p2-p1;
const typename Kernel::Vector3 e = p3-p1;
if(Kernel::isSame(d.norm(), 0., 1e-10)) {
if(Kernel::isSame(e.norm(), 0., 1e-10))
return calcOnePoint(p1);
return calcTwoPoints(p1, p3);
} else if(Kernel::isSame(e.norm(), 0., 1e-10)) {
return calcTwoPoints(p1, p2);
} else if(!Kernel::isSame((d/d.norm() - e/e.norm()).norm(), 0., 1e-10) &&
!Kernel::isSame((d/d.norm() + e/e.norm()).norm(), 0., 1e-10)) {
return calcThreePoints(p1, p2, p3);
}
//three points on a line need to be treaded as multiple points
}
//more than 3 points don't have a exact solution. we search for a midpoint from which all points
//are at least MAXFAKTOR*scale away, but not closer than MINFAKTOR*scale
//get the bonding box to get the center of points
Scalar xmin=1e10, xmax=1e-10, ymin=1e10, ymax=1e-10, zmin=1e10, zmax=1e-10;
for(iter it = m_points.begin(); it != m_points.end(); it++) {
typename Kernel::Vector3 v = (*it);
xmin = (v(0)<xmin) ? v(0) : xmin;
xmax = (v(0)<xmax) ? xmax : v(0);
ymin = (v(1)<ymin) ? v(1) : ymin;
ymax = (v(1)<ymax) ? ymax : v(1);
zmin = (v(2)<zmin) ? v(2) : zmin;
zmax = (v(2)<zmax) ? zmax : v(2);
};
//now calculate the midpoint
midpoint << xmin+xmax, ymin+ymax, zmin+zmax;
midpoint /= 2.;
//get the scale direction an the resulting nearest point indexes
double xh = xmax-xmin;
double yh = ymax-ymin;
double zh = zmax-zmin;
int i1, i2, i3;
if((xh<=yh) && (xh<=zh)) {
i1=1;
i2=2;
i3=0;
} else if((yh<xh) && (yh<zh)) {
i1=0;
i2=2;
i3=1;
} else {
i1=0;
i2=1;
i3=2;
}
scale_dir.setZero();
scale_dir(i3) = 1;
max = Eigen::Vector3d(xmin,ymin,zmin);
m_scale = (midpoint-max).norm()/MAXFAKTOR;
mode = multiple_inrange;
maxm = max-midpoint;
Scalar minscale = 1e10;
//get the closest point
for(iter it = m_points.begin(); it != m_points.end(); it++) {
const Eigen::Vector3d point = (*it)-midpoint;
if(point.norm()<MINFAKTOR*m_scale) {
const double h = std::abs(point(i3)-maxm(i3));
const double k = std::pow(MINFAKTOR/MAXFAKTOR,2);
double q = std::pow(point(i1),2) + std::pow(point(i2),2);
q -= (std::pow(maxm(i1),2) + std::pow(maxm(i2),2) + std::pow(h,2))*k;
q /= 1.-k;
const double p = h*k/(1.-k);
if(std::pow(p,2)<q) assert(false);
midpoint(i3) += p + std::sqrt(std::pow(p,2)-q);
maxm = max-midpoint;
m_scale = maxm.norm()/MAXFAKTOR;
mode = multiple_outrange;
minm = (*it)-midpoint;
it = m_points.begin();
} else if(point.norm()<minscale) {
minscale = point.norm();
}
}
if(mode==multiple_inrange) {
//we are in the range, let's get the perfect balanced scale value
m_scale = (minscale+maxm.norm())/2.;
}
return m_scale;
};
template<typename Sys>
void ClusterMath<Sys>::applyClusterScale(Scalar scale, bool isFixed) {
#ifdef USE_LOGGING
BOOST_LOG(log) << "Apply cluster scale: "<<scale;
BOOST_LOG(log) << "initial transform scale: "<<m_transform.scaling().factor();
#endif
//ensure the usage of the right transform
if(!fix)
mapsToTransform(m_transform);
//when fixed, the geometries never get recalculated. therefore we have to do a calculate now
//to allow the adoption of the scale. and no shift should been set.
if(isFixed) {
m_transform*=typename Kernel::Transform3D::Scaling(1./(scale*SKALEFAKTOR));
m_ssrTransform*=typename Kernel::Transform3D::Scaling(1./(scale*SKALEFAKTOR));
typename Kernel::DiffTransform3D diff(m_transform);
//now calculate the scaled geometries
typedef typename std::vector<Geom>::iterator iter;
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++) {
(*it)->recalculate(diff);
#ifdef USE_LOGGING
BOOST_LOG(log) << "Fixed cluster geometry value:" << (*it)->m_rotated.transpose();
#endif
};
return;
}
//if this is our scale then just apply the midpoint as shift
if(Kernel::isSame(scale, m_scale, 1e-10)) {
}
//if only one point exists we extend the origin-point-line to match the scale
else if(mode==details::one) {
if(Kernel::isSame(midpoint.norm(),0, 1e-10))
midpoint << scale, 0, 0;
else midpoint += scale*scale_dir;
}
//two and three points form a rectangular triangle, so same procedure
else if(mode==details::two || mode==details::three) {
midpoint+= scale_dir*std::sqrt(std::pow(scale,2) - std::pow(m_scale,2));
}
//multiple points
else if(mode==details::multiple_outrange) {
if(scale_dir(0)) {
Scalar d = std::pow(maxm(1),2) + std::pow(maxm(2),2);
Scalar h = std::sqrt(std::pow(MAXFAKTOR*scale,2)-d);
midpoint(0) += maxm(0) + h;
} else if(scale_dir(1)) {
Scalar d = std::pow(maxm(0),2) + std::pow(maxm(2),2);
Scalar h = std::sqrt(std::pow(MAXFAKTOR*scale,2)-d);
midpoint(1) += maxm(1) + h;
} else {
Scalar d = std::pow(maxm(0),2) + std::pow(maxm(1),2);
Scalar h = std::sqrt(std::pow(MAXFAKTOR*scale,2)-d);
midpoint(2) += maxm(2) + h;
}
} else {
//TODO: it's possible that for this case we get too far away from the outer points.
// The m_scale for "midpoint outside the bounding box" may be bigger than the
// scale to apply, so it results in an error.
//get the closest point
typedef typename Vec::iterator iter;
for(iter it = m_points.begin(); it != m_points.end(); it++) {
const Eigen::Vector3d point = (*it)-midpoint;
if(point.norm()<MINFAKTOR*scale) {
if(scale_dir(0)) {
Scalar d = std::pow(point(1),2) + std::pow(point(2),2);
Scalar h = std::sqrt(std::pow(MINFAKTOR*scale,2)-d);
midpoint(0) += point(0) + h;
} else if(scale_dir(1)) {
Scalar d = std::pow(point(0),2) + std::pow(point(2),2);
Scalar h = std::sqrt(std::pow(MINFAKTOR*scale,2)-d);
midpoint(1) += point(1) + h;
} else {
Scalar d = std::pow(point(0),2) + std::pow(point(1),2);
Scalar h = std::sqrt(std::pow(MINFAKTOR*scale,2)-d);
midpoint(2) += point(2) + h;
}
}
}
}
typename Kernel::Transform3D ssTrans;
ssTrans = typename Kernel::Transform3D::Translation(-midpoint);
ssTrans *= typename Kernel::Transform3D::Scaling(1./(scale*SKALEFAKTOR));
//recalculate all geometries
typedef typename std::vector<Geom>::iterator iter;
for(iter it = m_geometry.begin(); it != m_geometry.end(); it++)
(*it)->transform(ssTrans);
//set the new rotation and translation
m_transform = ssTrans.inverse()*m_transform;
m_ssrTransform *= ssTrans;
transformToMaps(m_transform);
#ifdef USE_LOGGING
BOOST_LOG(log) << "sstrans scale: "<<ssTrans.scaling().factor();
BOOST_LOG(log) << "finish transform scale: "<<m_transform.scaling().factor();
//we may want to access the scale points for debugging (I mean you, freecad assembly debug!), so
//it is important to transform them too to ensure the points are in the same coordinate system
typename Vec::iterator it;
for(it=m_points.begin(); it!=m_points.end(); it++) {
(*it) = ssTrans * (*it);
};
#endif
};
template<typename Sys>
typename ClusterMath<Sys>::Scalar ClusterMath<Sys>::calcOnePoint(const typename ClusterMath<Sys>::Kernel::Vector3& p) {
//one point can have every scale when moving the midpoint on the origin - point vector
midpoint = p;
scale_dir = -midpoint;
scale_dir.normalize();
mode = details::one;
m_scale = 0.;
return 0.;
};
template<typename Sys>
typename ClusterMath<Sys>::Scalar ClusterMath<Sys>::calcTwoPoints(const typename ClusterMath<Sys>::Kernel::Vector3& p1,
const typename ClusterMath<Sys>::Kernel::Vector3& p2) {
//two points have their minimal scale at the mid position. Scaling perpendicular to this
//line allows arbitrary scale values. Best is to have the scale dir move towards the origin
//as good as possible.
midpoint = p1+(p2-p1)/2.;
scale_dir = (p2-p1).cross(midpoint);
scale_dir = scale_dir.cross(p2-p1);
if(!Kernel::isSame(scale_dir.norm(),0, 1e-10)) scale_dir.normalize();
else scale_dir(0) = 1;
mode = details::two;
m_scale = (p2-p1).norm()/2.;
return m_scale;
};
template<typename Sys>
typename ClusterMath<Sys>::Scalar ClusterMath<Sys>::calcThreePoints(const typename ClusterMath<Sys>::Kernel::Vector3& p1,
const typename ClusterMath<Sys>::Kernel::Vector3& p2, const typename ClusterMath<Sys>::Kernel::Vector3& p3) {
//Three points form a triangle with its minimal scale at the center of its outer circle.
//Arbitrary scale values can be achieved by moving perpendicular to the triangle plane.
typename Kernel::Vector3 d = p2-p1;
typename Kernel::Vector3 e = p3-p1;
typename Kernel::Vector3 f = p1+0.5*d;
typename Kernel::Vector3 g = p1+0.5*e;
scale_dir = d.cross(e);
typename Kernel::Matrix3 m;
m.row(0) = d.transpose();
m.row(1) = e.transpose();
m.row(2) = scale_dir.transpose();
typename Kernel::Vector3 res(d.transpose()*f, e.transpose()*g, scale_dir.transpose()*p1);
midpoint = m.colPivHouseholderQr().solve(res);
scale_dir.normalize();
mode = details::three;
m_scale = (midpoint-p1).norm();
return m_scale;
};
}//details
}//dcm
#endif //GCM_CLUSTERMATH_H

View File

@@ -1,87 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CONSTRAINT_3D_HOLDER_IMP_H
#define DCM_CONSTRAINT_3D_HOLDER_IMP_H
#include "../geometry.hpp"
#include "opendcm/core/imp/constraint_holder_imp.hpp"
#ifdef DCM_EXTERNAL_CORE
//following macros are used for externalization. As the holder type can hold a very big set of combinations,
//especially with module states recursive incarnation, we explicitly initiate all possible versions of this
//struct so that it must only be compiled once. To get all possible equation
//combinations boost pp is needed.
template<typename T>
struct fusion_vec {
typedef typename mpl::if_< mpl::is_sequence<T>, T, fusion::vector1<T> >::type type;
};
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/for.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/push_front.hpp>
#include <boost/preprocessor/seq/remove.hpp>
#define TAG_SEQUENCE (dcm::tag::direction3D)(dcm::tag::point3D)(dcm::tag::line3D)(dcm::tag::plane3D)(dcm::tag::cylinder3D)
#define CONSTRAINT_SEQUENCE (dcm::Distance)(dcm::Orientation)(dcm::Angle)(dcm::Coincidence)(dcm::Alignment)
#define LEVEL_2_TYPE(r, state) \
template struct dcm::detail::Constraint<BOOST_PP_SEQ_ELEM(0,state), BOOST_PP_SEQ_ELEM(1,state)>::holder<fusion_vec<BOOST_PP_SEQ_ELEM(2,state)>::type, BOOST_PP_SEQ_ELEM(3,state), BOOST_PP_SEQ_ELEM(4,state)>;
#define LEVEL_2_TYPE_OP(r, state) \
BOOST_PP_SEQ_REMOVE(state,4)
#define LEVEL_2_TYPE_PRED(r, state) \
BOOST_PP_LESS(4,BOOST_PP_SEQ_SIZE(state))
#define LEVEL_1_TYPE(r, state) \
template struct dcm::detail::Constraint<BOOST_PP_SEQ_ELEM(0,state), BOOST_PP_SEQ_ELEM(1,state)>::holder<fusion_vec<BOOST_PP_SEQ_ELEM(2,state)>::type, BOOST_PP_SEQ_ELEM(3,state), BOOST_PP_SEQ_ELEM(3,state)>;\
BOOST_PP_FOR(state, LEVEL_2_TYPE_PRED, LEVEL_2_TYPE_OP, LEVEL_2_TYPE)
#define LEVEL_1_TYPE_OP(r, state) \
BOOST_PP_SEQ_REMOVE(state,3)
#define LEVEL_1_TYPE_PRED(r, state) \
BOOST_PP_LESS(3,BOOST_PP_SEQ_SIZE(state))
#define INITIALIZE_TYPES(System, Dim, Covec, SEQUENCE) \
BOOST_PP_FOR(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_FRONT(SEQUENCE, Covec), Dim), System), LEVEL_1_TYPE_PRED, LEVEL_1_TYPE_OP, LEVEL_1_TYPE)
#define LEVEL_1(r, state) \
INITIALIZE_TYPES(BOOST_PP_SEQ_ELEM(0,state), BOOST_PP_SEQ_ELEM(1,state), BOOST_PP_SEQ_ELEM(2,state), TAG_SEQUENCE) \
#define LEVEL_1_OP(r, state) \
BOOST_PP_SEQ_REMOVE(state,2)
#define LEVEL_1_PRED(r, state) \
BOOST_PP_LESS(2,BOOST_PP_SEQ_SIZE(state))
#define INITIALIZE(System, Dim, SEQUENCE) \
BOOST_PP_FOR(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_FRONT(SEQUENCE, Dim), System), LEVEL_1_PRED, LEVEL_1_OP, LEVEL_1)
#endif //external
#endif

View File

@@ -1,122 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CONSTRAINT_3D_IMP_H
#define DCM_CONSTRAINT_3D_IMP_H
#include "../module.hpp"
#ifdef DCM_EXTERNAL_CORE
#include "opendcm/core/imp/constraint_imp.hpp"
#include "opendcm/core/imp/object_imp.hpp"
#include "opendcm/core/imp/clustergraph_imp.hpp"
#endif
// #ifdef DCM_EXTERNAL_CORE
// //following macros are used for externalization. As constraint->initialize is very compiler intensive,
// //especially with module states recursive incarnation, we explicitly initiate all possible calls to this
// //function so that it must only be compiled once, one function at a time. To get all possible equation
// //combinations boost pp is needed.
//
// #include <boost/preprocessor.hpp>
// #include <boost/preprocessor/for.hpp>
// #include <boost/preprocessor/comparison/less.hpp>
// #include <boost/preprocessor/seq/size.hpp>
// #include <boost/preprocessor/seq/enum.hpp>
// #include <boost/preprocessor/seq/elem.hpp>
// #include <boost/preprocessor/seq/push_front.hpp>
// #include <boost/preprocessor/seq/remove.hpp>
/*
//
// #define SEQUENCE (dcm::Distance)(dcm::Orientation)(dcm::Angle)(dcm::Coincidence)(dcm::Alignment)
//
// #define LEVEL_1(r, state) \
// template void dcm::detail::Constraint<BOOST_PP_SEQ_ELEM(0,state), BOOST_PP_SEQ_ELEM(1,state)>::initialize(BOOST_PP_SEQ_ELEM(2,state)&); \
//
// #define LEVEL_1_OP(r, state) \
// BOOST_PP_SEQ_REMOVE(state,2)
//
// #define LEVEL_1_PRED(r, state) \
// BOOST_PP_LESS(2,BOOST_PP_SEQ_SIZE(state))
//
// #define INITIALIZE(System, Dim) \
// BOOST_PP_FOR(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_FRONT(SEQUENCE, Dim), System), LEVEL_1_PRED, LEVEL_1_OP, LEVEL_1)
//
// #endif //external
*/
namespace dcm {
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived> Module3D<Typelist, ID>::type<Sys>::Constraint3D_base<Derived>::clone(Sys& newSys) {
//copy the standard stuff
std::shared_ptr<Derived> np = std::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//copy the internals
np->content = CBase::content->clone();
//and get the geometry pointers right
if(CBase::first) {
GlobalVertex v = boost::static_pointer_cast<Geometry3D>(CBase::first)->template getProperty<vertex_prop>();
np->first = newSys.m_cluster->template getObject<Geometry3D>(v);
}
if(CBase::second) {
GlobalVertex v = boost::static_pointer_cast<Geometry3D>(CBase::second)->template getProperty<vertex_prop>();
np->second = newSys.m_cluster->template getObject<Geometry3D>(v);
}
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Constraint3D_id<Derived>::Constraint3D_id(Sys& system, Geom f, Geom s)
: Constraint3D_base<Derived>(system, f, s) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
typename Module3D<Typelist, ID>::template type<Sys>::Identifier&
Module3D<Typelist, ID>::type<Sys>::Constraint3D_id<Derived>::getIdentifier() {
return this->template getProperty<id_prop<Identifier> >();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Constraint3D_id<Derived>::setIdentifier(Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
};
template<typename Typelist, typename ID>
template<typename Sys>
Module3D<Typelist, ID>::type<Sys>::Constraint3D::Constraint3D(Sys& system, Geom first, Geom second)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Constraint3D_base<Constraint3D>,
Constraint3D_id<Constraint3D> >::type(system, first, second) {
};
} //dcm
#endif //DCM_MODULE_3D_IMP_H

View File

@@ -1,256 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GEOMETRY_3D_IMP_H
#define DCM_GEOMETRY_3D_IMP_H
#include "../module.hpp"
#ifdef DCM_EXTERNAL_CORE
#include "opendcm/core/imp/geometry_imp.hpp"
#include "opendcm/core/imp/object_imp.hpp"
#endif
namespace dcm {
namespace details {
template<typename Variant>
struct cloner : boost::static_visitor<void> {
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
//visitor to write the calculated value into the variant
template<typename Kernel>
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(typename Kernel::Vector& v) : value(v) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, value);
}
typename Kernel::Vector& value;
};
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::Geometry3D_base(Sys& system)
: Object<Sys, Derived, GeomSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::Geometry3D_base(const T& geometry, Sys& system)
: Object<Sys, Derived, GeomSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::set(const T& geometry) {
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
reset();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
T Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::convertTo() {
T t;
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, Base::m_global);
return t;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename Visitor>
typename Visitor::result_type Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::apply(Visitor& vis) {
return boost::apply_visitor(vis, m_geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived> Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::clone(Sys& newSys) {
//copy the standard stuff
std::shared_ptr<Derived> np = std::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//it's possible that the variant contains pointers, so we need to clone them
details::cloner<Variant> clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::recalculated() {
details::apply_visitor<Kernel> v(Base::getValue());
apply(v);
ObjBase::template emitSignal<dcm::recalculated>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::removed() {
ObjBase::template emitSignal<dcm::remove>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_base<Derived>::reset() {
ObjBase::template emitSignal<dcm::reset>(((Derived*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::Geometry3D_id(Sys& system)
: Module3D<Typelist, ID>::template type<Sys>::template Geometry3D_base<Derived>(system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::Geometry3D_id(const T& geometry, Sys& system)
: Module3D<Typelist, ID>::template type<Sys>::template Geometry3D_base<Derived>(geometry, system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::set(const T& geometry, Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::set(const T& geometry) {
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
typename Module3D<Typelist, ID>::template type<Sys>::Identifier&
Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::getIdentifier() {
return this->template getProperty<id_prop<Identifier> >();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void Module3D<Typelist, ID>::type<Sys>::Geometry3D_id<Derived>::setIdentifier(Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
#ifdef USE_LOGGING
std::stringstream str;
str<<this->template getProperty<id_prop<Identifier> >();
log_id.set(str.str());
BOOST_LOG(Base::log)<<"Identifyer set: "<<id;
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
Module3D<Typelist, ID>::type<Sys>::Geometry3D::Geometry3D(Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Geometry3D_base<Geometry3D>,
Geometry3D_id<Geometry3D> >::type(system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
Module3D<Typelist, ID>::type<Sys>::Geometry3D::Geometry3D(const T& geometry, Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Geometry3D_base<Geometry3D>,
Geometry3D_id<Geometry3D> >::type(geometry, system) {
};
} //dcm
#endif //DCM_MODULE_3D_IMP_H

View File

@@ -1,269 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE_3D_IMP_H
#define DCM_MODULE_3D_IMP_H
#include "../module.hpp"
#include <boost_bind_bind.hpp>
#include "constraint3d_imp.hpp"
#include "geometry3d_imp.hpp"
namespace bp = boost::placeholders;
namespace dcm {
namespace details {
// template<typename seq, typename t>
// struct distance {
// typedef typename mpl::find<seq, t>::type iterator;
// typedef typename mpl::distance<typename mpl::begin<seq>::type, iterator>::type type;
// BOOST_MPL_ASSERT((mpl::not_< boost::is_same<iterator, typename mpl::end<seq>::type > >));
// };
//build a constraint vector
template<typename T>
struct fusion_vec {
typedef typename mpl::if_< mpl::is_sequence<T>,
T, fusion::vector1<T> >::type type;
};
struct set_constraint_option {
template<typename T>
typename boost::enable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
operator()(T& val) {
return val;
};
template<typename T>
typename boost::disable_if<mpl::is_sequence<T>, typename fusion_vec<T>::type >::type
operator()(T& val) {
typename fusion_vec<T>::type vec;
fusion::at_c<0>(vec) = val;
return vec;
};
};
}
template<typename Typelist, typename ID>
template<typename Sys>
Module3D<Typelist, ID>::type<Sys>::inheriter_base::inheriter_base() {
m_this = ((Sys*) this);
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_base::createGeometry3D() {
Geom g(new Geometry3D(* ((Sys*) this)));
fusion::vector<LocalVertex, GlobalVertex> res = m_this->m_cluster->addVertex();
m_this->m_cluster->template setObject<Geometry3D> (fusion::at_c<0> (res), g);
g->template setProperty<vertex_prop>(fusion::at_c<1>(res));
m_this->push_back(g);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_base::createGeometry3D(T geom) {
Geom g(new Geometry3D(geom, * ((Sys*) this)));
fusion::vector<LocalVertex, GlobalVertex> res = m_this->m_cluster->addVertex();
m_this->m_cluster->template setObject<Geometry3D> (fusion::at_c<0> (res), g);
g->template setProperty<vertex_prop>(fusion::at_c<1>(res));
m_this->push_back(g);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_base::removeGeometry3D(Geom g) {
GlobalVertex v = g->template getProperty<vertex_prop>();
//check if this vertex holds a constraint
Cons c = m_this->m_cluster->template getObject<Constraint3D>(v);
if(c)
c->template emitSignal<remove>(c);
//emit remove geometry signal before actually deleting it, in case anyone wants to access the
//graph before
g->template emitSignal<remove>(g);
//remove the vertex from graph and emit all edges that get removed with the functor
boost::function<void(GlobalEdge)> functor = boost::bind(&inheriter_base::apply_edge_remove, this, bp::_1);
m_this->m_cluster->removeVertex(v, functor);
m_this->erase(g);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T1>
typename Module3D<Typelist, ID>::template type<Sys>::Cons
Module3D<Typelist, ID>::type<Sys>::inheriter_base::createConstraint3D(Geom first, Geom second, T1 constraint1) {
//get the fusion vector type
typedef typename details::fusion_vec<T1>::type covec;
//set the objects
covec cv = details::set_constraint_option()(constraint1);
//now create the constraint
Cons c(new Constraint3D(*m_this, first, second));
//initialize constraint
c->initialize(cv);
//add it to the clustergraph
fusion::vector<LocalEdge, GlobalEdge, bool, bool> res;
res = m_this->m_cluster->addEdge(first->template getProperty<vertex_prop>(),
second->template getProperty<vertex_prop>());
if(!fusion::at_c<2>(res)) {
Cons rc;
return rc; //TODO: throw
};
m_this->m_cluster->template setObject<Constraint3D> (fusion::at_c<1> (res), c);
//add the coresbondig edge to the constraint
c->template setProperty<edge_prop>(fusion::at_c<1>(res));
//store the constraint in general object vector of main system
m_this->push_back(c);
return c;
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_base::removeConstraint3D(Cons c) {
GlobalEdge e = c->template getProperty<edge_prop>();
c->template emitSignal<remove>(c);
m_this->m_cluster->removeEdge(e);
m_this->erase(c);
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_base::apply_edge_remove(GlobalEdge e) {
Cons c = m_this->m_cluster->template getObject<Constraint3D>(e);
c->template emitSignal<remove>(c);
m_this->erase(c);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_id::createGeometry3D(T geom, Identifier id) {
Geom g = inheriter_base::createGeometry3D(geom);
g->setIdentifier(id);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_id::createGeometry3D(Identifier id) {
Geom g = inheriter_base::createGeometry3D();
g->setIdentifier(id);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeGeometry3D(Identifier id) {
if(hasGeometry3D(id))
inheriter_base::removeGeometry3D(getGeometry3D(id));
else
throw module3d_error() << boost::errinfo_errno(410) << error_message("no geometry with this ID in this system");
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename Module3D<Typelist, ID>::template type<Sys>::Cons
Module3D<Typelist, ID>::type<Sys>::inheriter_id::createConstraint3D(Identifier id, Geom first, Geom second, T constraint1) {
Cons c = inheriter_base::createConstraint3D(first, second, constraint1);
c->setIdentifier(id);
return c;
};
template<typename Typelist, typename ID>
template<typename Sys>
void Module3D<Typelist, ID>::type<Sys>::inheriter_id::removeConstraint3D(Identifier id) {
if(hasConstraint3D(id))
removeConstraint3D(getConstraint3D(id));
else
throw module3d_error() << boost::errinfo_errno(411) << error_message("no constraint with this ID in this system");
};
template<typename Typelist, typename ID>
template<typename Sys>
bool Module3D<Typelist, ID>::type<Sys>::inheriter_id::hasGeometry3D(Identifier id) {
if(getGeometry3D(id))
return true;
return false;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Geom
Module3D<Typelist, ID>::type<Sys>::inheriter_id::getGeometry3D(Identifier id) {
std::vector< Geom >& vec = inheriter_base::m_this->template objectVector<Geometry3D>();
typedef typename std::vector<Geom>::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return Geom();
};
template<typename Typelist, typename ID>
template<typename Sys>
bool Module3D<Typelist, ID>::type<Sys>::inheriter_id::hasConstraint3D(Identifier id) {
if(getConstraint3D(id))
return true;
return false;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename Module3D<Typelist, ID>::template type<Sys>::Cons
Module3D<Typelist, ID>::type<Sys>::inheriter_id::getConstraint3D(Identifier id) {
std::vector< Cons >& vec = inheriter_base::m_this->template objectVector<Constraint3D>();
typedef typename std::vector<Cons>::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return Cons();
};
} //dcm
#endif //DCM_MODULE_3D_IMP_H

View File

@@ -1,495 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_SOLVER_3D_IMP_H
#define DCM_SOLVER_3D_IMP_H
#include "../solver.hpp"
#include "../defines.hpp"
#include <boost/graph/undirected_dfs.hpp>
#include <opendcm/core/kernel.hpp>
#ifdef DCM_EXTERNAL_CORE
#include "opendcm/core/imp/kernel_imp.hpp"
#include "opendcm/core/imp/clustergraph_imp.hpp"
#endif
namespace dcm {
namespace details {
template<typename Sys>
MES<Sys>::MES(std::shared_ptr<Cluster> cl, int par, int eqn) : Base(par, eqn), m_cluster(cl) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("MES3D"));
#endif
};
template<typename Sys>
void MES<Sys>::recalculate() {
//first calculate all clusters
typedef typename Cluster::cluster_iterator citer;
std::pair<citer, citer> cit = m_cluster->clusters();
for(; cit.first != cit.second; cit.first++) {
if(!(*cit.first).second->template getProperty<fix_prop>())
(*cit.first).second->template getProperty<math_prop>().recalculate();
};
//with everything updated just nicely we can compute the constraints
typedef typename Cluster::template object_iterator<Constraint3D> oiter;
typedef typename boost::graph_traits<Cluster>::edge_iterator eiter;
std::pair<eiter, eiter> eit = boost::edges(*m_cluster);
for(; eit.first != eit.second; eit.first++) {
//as always: every local edge can hold multiple global ones, so iterate over all constraints
//hold by the individual edge
std::pair< oiter, oiter > oit = m_cluster->template getObjects<Constraint3D>(*eit.first);
for(; oit.first != oit.second; oit.first++) {
if(*oit.first)
(*oit.first)->calculate(Base::Scaling, Base::m_access);
}
}
};
template<typename Sys>
void MES<Sys>::removeLocalGradientZeros() {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, information) << "remove local gradient zero";
#endif
//let the constraints treat the local zeros
typedef typename Cluster::template object_iterator<Constraint3D> oiter;
typedef typename boost::graph_traits<Cluster>::edge_iterator eiter;
std::pair<eiter, eiter> eit = boost::edges(*m_cluster);
for(; eit.first != eit.second; eit.first++) {
//as always: every local edge can hold multiple global ones, so iterate over all constraints
//hold by the individual edge
std::pair< oiter, oiter > oit = m_cluster->template getObjects<Constraint3D>(*eit.first);
for(; oit.first != oit.second; oit.first++) {
if(*oit.first)
(*oit.first)->treatLGZ();
}
}
};
template<typename Sys>
SystemSolver<Sys>::Rescaler::Rescaler(std::shared_ptr<Cluster> c, Mes& m) : cluster(c), mes(m), rescales(0) {
};
template<typename Sys>
void SystemSolver<Sys>::Rescaler::operator()() {
const Scalar sc = calculateScale();
if(sc<MINFAKTOR || sc>MAXFAKTOR)
mes.Scaling = scaleClusters(sc);
rescales++;
};
template<typename Sys>
typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::calculateScale() {
typedef typename Cluster::cluster_iterator citer;
std::pair<citer, citer> cit = cluster->clusters();
//get the maximal scale
Scalar sc = 0;
for(cit = cluster->clusters(); cit.first != cit.second; cit.first++) {
//fixed cluster are irrelevant for scaling
if((*cit.first).second->template getProperty<fix_prop>())
continue;
//get the biggest scale factor
details::ClusterMath<Sys>& math = (*cit.first).second->template getProperty<math_prop>();
math.m_pseudo.clear();
collectPseudoPoints(cluster, (*cit.first).first, math.m_pseudo);
const Scalar s = math.calculateClusterScale();
sc = (s>sc) ? s : sc;
}
return sc;
}
template<typename Sys>
typename SystemSolver<Sys>::Scalar SystemSolver<Sys>::Rescaler::scaleClusters(Scalar sc) {
//if no scaling-value returned we can use 1
sc = (Kernel::isSame(sc,0, 1e-10)) ? 1. : sc;
typedef typename boost::graph_traits<Cluster>::vertex_iterator iter;
std::pair<iter, iter> it = boost::vertices(*cluster);
for(; it.first != it.second; it.first++) {
if(cluster->isCluster(*it.first)) {
std::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
c->template getProperty<math_prop>().applyClusterScale(sc,
c->template getProperty<fix_prop>());
}
else {
Geom g = cluster->template getObject<Geometry3D>(*it.first);
g->scale(sc*SKALEFAKTOR);
}
}
return 1./(sc*SKALEFAKTOR);
};
template<typename Sys>
void SystemSolver<Sys>::Rescaler::collectPseudoPoints(
std::shared_ptr<typename SystemSolver<Sys>::Cluster> parent,
LocalVertex cluster,
std::vector<typename SystemSolver<Sys>::Kernel::Vector3,
Eigen::aligned_allocator<typename SystemSolver<Sys>::Kernel::Vector3> >& vec) {
std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > vec2;
typedef typename Cluster::global_edge_iterator c_iter;
typedef typename boost::graph_traits<Cluster>::out_edge_iterator e_iter;
std::pair<e_iter, e_iter> it = boost::out_edges(cluster, *parent);
for(; it.first != it.second; it.first++) {
std::pair< c_iter, c_iter > cit = parent->getGlobalEdges(*it.first);
for(; cit.first != cit.second; cit.first++) {
Cons c = parent->template getObject<Constraint3D>(*cit.first);
if(!c)
continue;
//get the first global vertex and see if we have it in the wanted cluster or not
GlobalVertex v = cit.first->source;
std::pair<LocalVertex,bool> res = parent->getLocalVertex(v);
if(!res.second)
return; //means the geometry is in none of the clusters which is not allowed
if(res.first == cluster)
c->collectPseudoPoints(vec, vec2);
else
c->collectPseudoPoints(vec2, vec);
}
}
};
template<typename Sys>
SystemSolver<Sys>::SystemSolver() {
Job<Sys>::priority = 1000;
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("SystemSolver3D"));
#endif
};
template<typename Sys>
void SystemSolver<Sys>::execute(Sys& sys) {
solveCluster(sys.m_cluster, sys);
};
template<typename Sys>
void SystemSolver<Sys>::solveCluster(std::shared_ptr<Cluster> cluster, Sys& sys) {
//set out and solve all relevant subclusters
typedef typename Cluster::cluster_iterator citer;
std::pair<citer, citer> cit = cluster->clusters();
for(; cit.first != cit.second; cit.first++) {
std::shared_ptr<Cluster> c = (*cit.first).second;
if(c->template getProperty<changed_prop>() &&
((c->template getProperty<type_prop>() == details::cluster3D)
|| ((c->template getProperty<type_prop>() == details::subcluster) &&
(sys.template getOption<subsystemsolving>() == Automatic))))
solveCluster(c, sys);
}
int params=0, constraints=0;
typename Kernel::number_type scale = 1;
//get the amount of parameters and constraint equations we need
typedef typename boost::graph_traits<Cluster>::vertex_iterator iter;
std::pair<iter, iter> it = boost::vertices(*cluster);
for(; it.first != it.second; it.first++) {
//when cluster and not fixed it has trans and rot parameter
if(cluster->isCluster(*it.first)) {
if(!cluster->template getSubclusterProperty<fix_prop>(*it.first)) {
params += 6;
}
}
else {
params += cluster->template getObject<Geometry3D>(*it.first)->m_parameterCount;
};
}
//count the equations in the constraints
typedef typename Cluster::template object_iterator<Constraint3D> ocit;
typedef typename boost::graph_traits<Cluster>::edge_iterator e_iter;
std::pair<e_iter, e_iter> e_it = boost::edges(*cluster);
for(; e_it.first != e_it.second; e_it.first++) {
std::pair< ocit, ocit > it = cluster->template getObjects<Constraint3D>(*e_it.first);
for(; it.first != it.second; it.first++)
constraints += (*it.first)->equationCount();
};
if(params <= 0 || constraints <= 0) {
//TODO:throw
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, error)<< "Error in system counting: params = " << params << " and constraints = "<<constraints;
#endif
return;
}
//initialise the system with now known size
Mes mes(cluster, params, constraints);
//iterate all geometries again and set the needed maps
it = boost::vertices(*cluster);
for(; it.first != it.second; it.first++) {
if(cluster->isCluster(*it.first)) {
std::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
details::ClusterMath<Sys>& cm = c->template getProperty<math_prop>();
//only get maps and propagate downstream if not fixed
if(!c->template getProperty<fix_prop>()) {
//set norm Quaternion as map to the parameter vector
int offset_rot = mes.setParameterMap(cm.getNormQuaternionMap(), rotation);
//set translation as map to the parameter vector
int offset = mes.setParameterMap(cm.getTranslationMap(), general);
//write initial values to the parameter maps
//remember the parameter offset as all downstream geometry must use this offset
cm.setParameterOffset(offset_rot, rotation);
cm.setParameterOffset(offset, general);
//write initial values
cm.initMaps();
}
else
cm.initFixMaps();
//map all geometries within that cluster to it's rotation matrix
//for collecting all geometries which need updates
cm.clearGeometry();
cm.mapClusterDownstreamGeometry(c);
}
else {
Geom g = cluster->template getObject<Geometry3D>(*it.first);
g->initMap(&mes);
}
}
//and now the constraints to set the residual and gradient maps
typedef typename Cluster::template object_iterator<Constraint3D> oiter;
e_it = boost::edges(*cluster);
for(; e_it.first != e_it.second; e_it.first++) {
//as always: every local edge can hold multiple global ones, so iterate over all constraints
//hold by the individual edge
std::pair< oiter, oiter > oit = cluster->template getObjects<Constraint3D>(*e_it.first);
for(; oit.first != oit.second; oit.first++) {
//set the maps
Cons c = *oit.first;
if(c)
c->setMaps(mes);
//TODO: else throw (as every global edge was counted as one equation)
}
}
try {
//if we don't have rotations we need no expensive scaling code
if(!mes.hasAccessType(rotation)) {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<< "No rotation parameters in system, solve without scaling";
#endif
DummyScaler re;
sys.kernel().solve(mes, re);
}
else {
// we have rotations, so let's check our options. first search for cycles, as systems with them
// always need the full solver power
bool has_cycle;
cycle_dedector cd(has_cycle);
//create the needed property maps and fill it
property_map<vertex_index_prop, Cluster> vi_map(cluster);
cluster->initIndexMaps();
typedef std::map< LocalVertex, boost::default_color_type> vcmap;
typedef std::map< LocalEdge, boost::default_color_type> ecmap;
vcmap v_cm;
ecmap e_cm;
boost::associative_property_map< vcmap > v_cpm(v_cm);
boost::associative_property_map< ecmap > e_cpm(e_cm);
boost::undirected_dfs(*cluster.get(), boost::visitor(cd).vertex_index_map(vi_map).vertex_color_map(v_cpm).edge_color_map(e_cpm));
bool done = false;
if(!has_cycle) {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<< "non-cyclic system detected: solve rotation only";
#endif
//cool, lets do uncylic. first all rotational constraints with rotational parameters
mes.setAccess(rotation);
//rotations need to be calculated in a scaled manner. that's because the normals used for
//rotation calculation are always 1, no matter how big the part is. This can lead to problems
//when for example two rotated faces have a precision error on the parallel normals but a distance
//at the outer edges is far bigger than the precision as the distance from normal origin to outer edge
//is bigger 1. that would lead to unsolvable translation-only systems.
//solve need to catch exceptions to reset the mes scaling on failure
Rescaler re(cluster, mes);
mes.Scaling = 1./(re.calculateScale()*SKALEFAKTOR);
try {
DummyScaler dummy;
sys.kernel().solve(mes, dummy);
mes.Scaling = 1.;
}
catch(...) {
mes.Scaling = 1.;
throw;
}
//now let's see if we have to go on with the translations
if(mes.hasAccessType(general)) {
mes.setAccess(general);
mes.recalculate();
if(sys.kernel().isSame(mes.Residual.template lpNorm<E::Infinity>(),0.))
done = true;
else {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<< "Solve Translation after Rotations are not enough";
#endif
//let's try translation only
try {
DummyScaler re;
sys.kernel().solve(mes, re);
done=true;
}
catch(boost::exception&) {
//not successful, so we need brute force
done = false;
}
}
};
}
else {
throw solving_error() << boost::errinfo_errno(22) << error_message("Cyclic system are not yet supported");
}
//not done already? try it the hard way!
if(!done) {
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<< "Full scale solver used";
#endif
mes.setAccess(complete);
mes.recalculate();
Rescaler re(cluster, mes);
re();
sys.kernel().solve(mes, re);
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, solving)<< "Numbers of rescale: "<<re.rescales;
#endif
};
}
//done solving, write the results back
finish(cluster, sys, mes);
}
catch(boost::exception&) {
if(sys.template getOption<solverfailure>()==ApplyResults)
finish(cluster, sys, mes);
else
throw;
}
};
template<typename Sys>
void SystemSolver<Sys>::finish(std::shared_ptr<Cluster> cluster, Sys& sys, Mes& mes) {
//solving is done, now go to all relevant geometries and clusters and write the values back
//(no need to emit recalculated signal as this cluster is never recalculated in this run)
typedef typename boost::graph_traits<Cluster>::vertex_iterator iter;
std::pair<iter, iter> it = boost::vertices(*cluster);
for(; it.first != it.second; it.first++) {
if(cluster->isCluster(*it.first)) {
std::shared_ptr<Cluster> c = cluster->getVertexCluster(*it.first);
if(!cluster->template getSubclusterProperty<fix_prop>(*it.first))
c->template getProperty<math_prop>().finishCalculation();
else
c->template getProperty<math_prop>().finishFixCalculation();
std::vector<Geom>& vec = c->template getProperty<math_prop>().getGeometry();
for(typename std::vector<Geom>::iterator vit = vec.begin(); vit != vec.end(); vit++)
(*vit)->finishCalculation();
}
else {
Geom g = cluster->template getObject<Geometry3D>(*it.first);
g->scale(mes.Scaling);
g->finishCalculation();
}
}
//we have solved this cluster
cluster->template setProperty<changed_prop>(false);
}
}//details
}//dcm
#endif //DCM_SOLVER_3D_HPP

View File

@@ -1,468 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE3D_STATE_IMP_HPP
#define DCM_MODULE3D_STATE_IMP_HPP
#include "../state.hpp"
#include "../module.hpp"
#include "../coincident.hpp"
#include "../alignment.hpp"
#include <boost/spirit/include/phoenix.hpp>
#include <boost/phoenix/function/adapt_function.hpp>
#include <boost/phoenix/bind.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/phoenix/fusion/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/tokenizer.hpp>
namespace karma_ascii = boost::spirit::karma::ascii;
namespace qi_ascii = boost::spirit::qi::ascii;
namespace phx = boost::phoenix;
#include <ios>
namespace karma = boost::spirit::karma;
namespace qi = boost::spirit::qi;
namespace karma_ascii = boost::spirit::karma::ascii;
namespace qi_ascii = boost::spirit::qi::ascii;
namespace phx = boost::phoenix;
namespace dcm {
namespace details {
struct geom_visitor : public boost::static_visitor<std::string> {
template<typename T>
std::string operator()(T& i) const {
//we use strings in case new geometry gets added and the weights shift, meaning: backwards
//compatible
std::string type;
switch(geometry_traits<T>::tag::weight::value) {
case tag::weight::direction::value :
return "direction";
case tag::weight::point::value :
return "point";
case tag::weight::line::value :
return "line";
case tag::weight::plane::value :
return "plane";
case tag::weight::cylinder::value :
return "cylinder";
default:
return "unknown";
};
};
};
template<typename T>
std::string getWeight(std::shared_ptr<T> ptr) {
geom_visitor v;
return ptr->apply(v);
};
template<typename T>
struct get_weight {
typedef typename geometry_traits<T>::tag::weight type;
};
//search the first type in the typevector with the given weight
template<typename Vector, typename Weight>
struct getWeightType {
typedef typename mpl::find_if<Vector, boost::is_same<get_weight<mpl::_1>, Weight > >::type iter;
typedef typename mpl::if_< boost::is_same<iter, typename mpl::end<Vector>::type >, mpl::void_, typename mpl::deref<iter>::type>::type type;
};
typedef std::vector< fusion::vector2<std::string, std::vector<double> > > string_vec;
typedef std::vector< fusion::vector2<std::vector<char>, std::vector<double> > > char_vec;
template<typename C>
string_vec getConstraints(std::shared_ptr<C> con) {
string_vec vec;
std::vector<boost::any> cvec = con->getGenericConstraints();
boost::any al_o, d;
typename std::vector<boost::any>::iterator it;
if(cvec.size()==1) {
it = cvec.begin();
if((*it).type() == typeid(dcm::Distance)) {
double v = fusion::at_key<double>(boost::any_cast<dcm::Distance>(*it).values).second;
SolutionSpace s = fusion::at_key<SolutionSpace>(boost::any_cast<dcm::Distance>(*it).values).second;
std::vector<double> dvec;
dvec.push_back(v);
dvec.push_back(s);
vec.push_back(fusion::make_vector(std::string("Distance"), dvec));
}
else if((*it).type() == typeid(dcm::Angle)) {
double v = fusion::at_key<double>(boost::any_cast<dcm::Angle>(*it).values).second;
std::vector<double> value;
value.push_back(v);
vec.push_back(fusion::make_vector(std::string("Angle"), value));
}
else if((*it).type() == typeid(dcm::Orientation)) {
int v = fusion::at_key<dcm::Direction>(boost::any_cast<dcm::Orientation>(*it).values).second;
std::vector<double> value;
value.push_back(v);
vec.push_back(fusion::make_vector(std::string("Orientation"), value));
}
}
else {
for(it=cvec.begin(); it!=cvec.end(); it++) {
if((*it).type() == typeid(dcm::details::ci_orientation)) {
int v = fusion::at_key<dcm::Direction>(boost::any_cast<dcm::details::ci_orientation>(*it).values).second;
std::vector<double> value;
value.push_back(v);
vec.push_back(fusion::make_vector(std::string("Coincidence"), value));
}
else if((*it).type() == typeid(dcm::details::al_orientation)) {
int o = fusion::at_key<dcm::Direction>(boost::any_cast<dcm::details::al_orientation>(*it).values).second;
double v;
SolutionSpace s;
if(it==cvec.begin()) {
v = fusion::at_key<double>(boost::any_cast<dcm::Distance>(cvec.back()).values).second;
s = fusion::at_key<SolutionSpace>(boost::any_cast<dcm::Distance>(cvec.back()).values).second;
}
else {
v = fusion::at_key<double>(boost::any_cast<dcm::Distance>(cvec.front()).values).second;
s = fusion::at_key<SolutionSpace>(boost::any_cast<dcm::Distance>(cvec.front()).values).second;
}
std::vector<double> value;
value.push_back(o);
value.push_back(v);
value.push_back(s);
vec.push_back(fusion::make_vector(std::string("Alignment"), value));
};
}
}
return vec;
};
template<typename C>
void constraintCreation(typename char_vec::iterator it,
typename char_vec::iterator end,
std::shared_ptr<C> con) {
std::string first(fusion::at_c<0>(*it).begin(), fusion::at_c<0>(*it).end());
std::vector<double> second = fusion::at_c<1>(*it);
if(first.compare("Distance") == 0) {
typename details::fusion_vec<dcm::Distance>::type val;
(fusion::front(val)=second[0])= (SolutionSpace)second[1];
con->template initialize(val);
return;
}
else if(first.compare("Orientation") == 0) {
typename details::fusion_vec<dcm::Orientation>::type val;
fusion::front(val)= (dcm::Direction)second[0];
con->template initialize(val);
return;
}
else if(first.compare("Angle") == 0) {
typename details::fusion_vec<dcm::Angle>::type val;
fusion::front(val)=second[0];
con->template initialize(val);
return;
}
else if(first.compare("Coincidence") == 0) {
typename details::fusion_vec<dcm::Coincidence>::type val;
val= (dcm::Direction)second[0];
con->template initialize(val);
return;
}
else if(first.compare("Alignment") == 0) {
typename details::fusion_vec<dcm::Alignment>::type val;
((val=(dcm::Direction)second[0])=second[1])=(dcm::SolutionSpace)second[2];
con->template initialize(val);
return;
}
};
template<typename C>
void setConstraints(char_vec& vec, std::shared_ptr<C> con) {
constraintCreation<C>(vec.begin(), vec.end(), con);
};
template <typename Geom, typename Row, typename Value>
bool VectorOutput(Geom& v, Row& r, Value& val) {
if(r < v->m_global.rows()) {
val = v->m_global(r++);
return true; // output continues
}
return false; // fail the output
};
template <typename Geom, typename Row, typename Value>
bool VectorInput(Geom& v, Row& r, Value& val) {
v.conservativeResize(r+1);
v(r++) = val;
return true; // output continues
};
template <typename Translation, typename Row, typename Value>
bool TranslationOutput(Translation& v, Row& r, Value& val) {
if(r < 3) {
val = v.getTranslation().vector()(r++);
return true; // output continues
}
return false; // fail the output
};
template <typename CM>
bool TranslationInput(CM& t, std::vector<double> const& val) {
t.setTranslation(typename CM::Kernel::Transform3D::Translation(val[0],val[1],val[2]));
return true; // output continues
};
template <typename CM, typename Row, typename Value>
bool RotationOutput(CM& v, Row& r, Value& val) {
if(r < 3) {
val = v.getRotation().vec()(r++);
return true; // output continues
}
else if( r < 4 ) {
val = v.getRotation().w();
return true;
}
return false; // fail the output
};
template <typename CM>
bool RotationInput(CM& t, std::vector<double> const& val) {
t.setRotation(typename CM::Kernel::Transform3D::Rotation(val[3], val[0], val[1], val[2]));
return true; // output continues
};
template<typename Geom>
struct inject_set {
template<typename Vec, typename Obj>
static void apply(Vec& v, Obj g) {
Geom gt;
(typename geometry_traits<Geom>::modell()).template inject<double,
typename geometry_traits<Geom>::accessor >(gt, v);
g->set(gt);
};
};
//specialization if no type in the typelist has the right weight
template<>
struct inject_set<mpl::void_> {
template<typename Obj, typename Vec>
static void apply(Vec& v, Obj g) {
//TODO:throw
};
};
template<typename System>
bool Create(System* sys, std::string& type,
std::shared_ptr<typename details::getModule3D<System>::type::Geometry3D> geom,
typename System::Kernel::Vector& v) {
typedef typename details::getModule3D<System>::type::geometry_types Typelist;
if(type.compare("direction") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::direction>::type>::apply(v, geom);
}
else if(type.compare("point") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::point>::type>::apply(v, geom);
}
else if(type.compare("line") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::line>::type>::apply(v, geom);
}
else if(type.compare("plane") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::plane>::type>::apply(v, geom);
}
else if(type.compare("cylinder") == 0) {
inject_set<typename getWeightType<Typelist, tag::weight::cylinder>::type>::apply(v, geom);
};
return true;
};
// define a new real number formatting policy
template <typename Num>
struct scientific_policy : karma::real_policies<Num>
{
// we want the numbers always to be in scientific format
static int floatfield(Num n) {
return std::ios::scientific;
}
static unsigned precision(Num n) {
return 16;
};
};
// define a new generator type based on the new policy
typedef karma::real_generator<double, scientific_policy<double> > science_type;
static science_type const scientific = science_type();
} //details
} //dcm
BOOST_PHOENIX_ADAPT_FUNCTION(bool, vector_out, dcm::details::VectorOutput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION(bool, vector_in, dcm::details::VectorInput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION(bool, translation_out, dcm::details::TranslationOutput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION(bool, rotation_out, dcm::details::RotationOutput, 3)
BOOST_PHOENIX_ADAPT_FUNCTION(bool, create, dcm::details::Create, 4)
BOOST_FUSION_ADAPT_STRUCT(
dcm::GlobalEdge,
(int, ID)
(int, source)
(int, target)
)
namespace dcm {
template<typename System, typename iterator>
void parser_generator< typename details::getModule3D<System>::type::Geometry3D , System, iterator >::init(generator& r) {
r = karma::lit("<type>Geometry3D</type>\n<class>")
<< karma_ascii::string[karma::_1 = phx::bind(&details::getWeight<Geometry>, karma::_val)]
<< "</class>" << karma::eol << "<value>"
<< (details::scientific[ boost::spirit::_pass = vector_out(karma::_val, karma::_a, karma::_1) ] % ' ')
<< "</value>";
};
template<typename System, typename iterator>
void parser_generator< typename details::getModule3D<System>::type::vertex_prop , System, iterator >::init(generator& r) {
r = karma::lit("<type>Vertex</type>")
<< karma::eol << "<value>" << karma::int_ << "</value>";
};
/*
template<typename System, typename iterator>
void parser_generator< typename details::getModule3D<System>::type::math_prop , System, iterator >::init(generator& r) {
r = karma::lit("<type>Math3D</type>")
<< karma::eol << "<Translation>" << (details::scientific[ boost::spirit::_pass = translation_out(karma::_val, karma::_a, karma::_1) ] % ' ') << "</Translation>"
<< karma::eol << karma::eps[karma::_a = 0] << "<Rotation>" << (details::scientific[ boost::spirit::_pass = rotation_out(karma::_val, karma::_a, karma::_1) ] % ' ') << "</Rotation>";
};*/
template<typename System, typename iterator>
void parser_generator< typename details::getModule3D<System>::type::Constraint3D , System, iterator >::init(generator& r) {
r = karma::lit("<type>Constraint3D</type>") << karma::eol
<< "<connect first=" << karma::int_[karma::_1 = phx::at_c<1>(phx::bind(&Constraint3D::template getProperty<edge_prop>, karma::_val))]
<< " second=" << karma::int_[karma::_1 = phx::at_c<2>(phx::bind(&Constraint3D::template getProperty<edge_prop>, karma::_val))] << "></connect>"
<< (*(karma::eol<<"<constraint type="<<karma_ascii::string<<">"<<*(karma::double_<<" ")<<"</constraint>"))[karma::_1 = phx::bind(&details::getConstraints<Constraint3D>, karma::_val)];
};
template<typename System, typename iterator>
void parser_generator< typename details::getModule3D<System>::type::edge_prop , System, iterator >::init(generator& r) {
r %= karma::lit("<type>Edge</type>")
<< karma::eol << "<value>" << karma::int_ << " "
<< karma::int_ << " " << karma::int_ << "</value>";
};
template<typename System, typename iterator>
void parser_generator<typename details::getModule3D<System>::type::fix_prop, System, iterator>::init(generator& r) {
r = karma::lit("<type>Fix</type>\n<value>") << karma::bool_ <<"</value>";
};
/****************************************************************************************************/
/****************************************************************************************************/
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::Geometry3D, System, iterator >::init(parser& r) {
r = qi::lit("<type>Geometry3D</type>")[ qi::_val = phx::construct<std::shared_ptr<object_type> >(phx::new_<object_type>(*qi::_r1))]
>> "<class>" >> (+qi::char_("a-zA-Z"))[qi::_a = phx::construct<std::string>(phx::begin(qi::_1), phx::end(qi::_1))] >> "</class>"
>> "<value>" >> *qi::double_[ vector_in(qi::_b, qi::_c, qi::_1) ] >> "</value>"
>> qi::eps[ create(qi::_r1, qi::_a, qi::_val, qi::_b) ];
};
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::vertex_prop, System, iterator >::init(parser& r) {
r %= qi::lit("<type>Vertex</type>") >> "<value>" >> qi::int_ >> "</value>";
};
/*
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::math_prop, System, iterator >::init(parser& r) {
//r = qi::lit("<type>Math3D</type>") >> "<Translation>" >> (*qi::double_)[ phx::bind(&details::TranslationInput<details::ClusterMath<System> >, qi::_val, qi::_1) ] >> "</Translation>"
// >> "<Rotation>" >> (*qi::double_)[ phx::bind(&details::RotationInput<details::ClusterMath<System> >,qi::_val, qi::_1) ] >> "</Rotation>";
};*/
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::Constraint3D, System, iterator >::init(parser& r) {
r = qi::lit("<type>Constraint3D</type>")
>> ("<connect first=" >> qi::int_ >> "second=" >> qi::int_ >> "></connect>")[
qi::_val = phx::construct<std::shared_ptr<Constraint3D> >(
phx::new_<Constraint3D>(*qi::_r1,
phx::bind(&System::Cluster::template getObject<Geometry3D, GlobalVertex>, phx::bind(&System::m_cluster, qi::_r1), qi::_1),
phx::bind(&System::Cluster::template getObject<Geometry3D, GlobalVertex>, phx::bind(&System::m_cluster, qi::_r1), qi::_2)))
]
>> (*("<constraint type=" >> *qi_ascii::alpha >> ">" >> *qi::double_ >>"</constraint>"))[phx::bind(&details::setConstraints<Constraint3D>, qi::_1, qi::_val)];
};
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::edge_prop, System, iterator >::init(parser& r) {
r %= qi::lit("<type>Edge</type>")
>> "<value>" >> qi::int_ >> qi::int_ >> qi::int_ >> "</value>";
};
template<typename System, typename iterator>
void parser_parser< typename details::getModule3D<System>::type::fix_prop, System, iterator >::init(parser& r) {
r = qi::lit("<type>Fix</type>") >> "<value>" >> qi::bool_ >> "</value>";
};
}
#endif //DCM_MODULE3D_STATE_HPP

View File

@@ -1,335 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE_3D_H
#define DCM_MODULE_3D_H
#include <boost/mpl/vector.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/if.hpp>
#include <memory>
#include <boost/variant.hpp>
#include <boost/function.hpp>
#include "opendcm/core.hpp"
#include "opendcm/core/object.hpp"
#include "opendcm/core/geometry.hpp"
#include "opendcm/core/clustergraph.hpp"
#include "opendcm/core/scheduler.hpp"
#include "opendcm/core/traits.hpp"
#include "geometry.hpp"
#include "distance.hpp"
#include "parallel.hpp"
#include "angle.hpp"
#include "solver.hpp"
#include "defines.hpp"
#include "clustermath.hpp"
namespace mpl = boost::mpl;
namespace dcm {
struct reset {}; //signal name
struct module3d_error : virtual boost::exception {}; //exception for all module3d special errors
template<typename Typelist, typename ID = No_Identifier>
struct Module3D {
template<typename Sys>
struct type : details::m3d {
struct Constraint3D;
struct Geometry3D;
struct vertex_prop;
struct inheriter_base;
typedef std::shared_ptr<Geometry3D> Geom;
typedef std::shared_ptr<Constraint3D> Cons;
typedef mpl::map3< mpl::pair<reset, boost::function<void (Geom) > >,
mpl::pair<remove, boost::function<void (Geom) > > ,
mpl::pair<recalculated, boost::function<void (Geom)> > > GeomSig;
typedef mpl::map1< mpl::pair<remove, boost::function<void (Cons) > > > ConsSignal;
typedef ID Identifier;
typedef Typelist geometry_types;
typedef details::MES<Sys> MES;
typedef details::SystemSolver<Sys> SystemSolver;
template<typename Derived>
class Geometry3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>,
public Object<Sys, Derived, GeomSig> {
typedef details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries> Base;
typedef Object<Sys, Derived, GeomSig> ObjBase;
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
public:
Geometry3D_base(Sys& system);
template<typename T>
Geometry3D_base(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry);
bool holdsType() {
return m_geometry.which()!=0;
};
int whichType() {
return m_geometry.which()-1;
};
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis);
template<typename T>
T convertTo();
virtual std::shared_ptr<Derived> clone(Sys& newSys);
protected:
typedef typename mpl::push_front<Typelist, boost::blank>::type ExtTypeList;
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
#ifdef USE_LOGGING
src::logger log;
#endif
Variant m_geometry; //Variant holding the real geometry type
//override protected event functions to emit signals
void reset();
void recalculated();
void removed();
friend struct Constraint3D;
};
template<typename Derived>
class Geometry3D_id : public Geometry3D_base<Derived> {
typedef Geometry3D_base<Derived> Base;
#ifdef USE_LOGGING
attrs::mutable_constant< std::string > log_id;
#endif
public:
Geometry3D_id(Sys& system);
template<typename T>
Geometry3D_id(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry, Identifier id);
//somehow the base class set function is not found
template<typename T>
void set(const T& geometry);
Identifier& getIdentifier();
void setIdentifier(Identifier id);
};
struct Geometry3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
Geometry3D_base<Geometry3D>, Geometry3D_id<Geometry3D> >::type {
typedef vertex_prop vertex_propertie;
Geometry3D(Sys& system);
template<typename T>
Geometry3D(const T& geometry, Sys& system);
//allow accessing the internals by module3d classes but not by users
friend struct details::ClusterMath<Sys>;
friend struct details::ClusterMath<Sys>::map_downstream;
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct inheriter_base;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
template<typename Derived>
class Constraint3D_base : public detail::Constraint<Sys, 3>, public Object<Sys, Derived, ConsSignal> {
typedef detail::Constraint<Sys, 3> CBase;
public:
Constraint3D_base(Sys& system, Geom f, Geom s) : detail::Constraint<Sys, 3>(f,s),
Object<Sys, Derived, ConsSignal>(system) {};
virtual std::shared_ptr<Derived> clone(Sys& newSys);
};
template<typename Derived>
class Constraint3D_id : public Constraint3D_base<Derived> {
typedef Constraint3D_base<Derived> base;
public:
Constraint3D_id(Sys& system, Geom f, Geom s);
Identifier& getIdentifier();
void setIdentifier(Identifier id);
};
struct Constraint3D : public mpl::if_<boost::is_same<Identifier, No_Identifier>,
Constraint3D_base<Constraint3D>,
Constraint3D_id<Constraint3D> >::type {
Constraint3D(Sys& system, Geom first, Geom second);
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct details::MES<Sys>;
friend struct inheriter_base;
};
struct inheriter_base {
inheriter_base();
template<typename T>
Geom createGeometry3D(T geom);
Geom createGeometry3D();
void removeGeometry3D(Geom g);
template<typename T1>
Cons createConstraint3D(Geom first, Geom second, T1 constraint1);
void removeConstraint3D(Cons c);
void system_sub(std::shared_ptr<Sys> subsys) {};
protected:
Sys* m_this;
void apply_edge_remove(GlobalEdge e);
};
struct inheriter_id : public inheriter_base {
protected:
using inheriter_base::m_this;
public:
using inheriter_base::createGeometry3D;
using inheriter_base::createConstraint3D;
template<typename T>
Geom createGeometry3D(T geom, Identifier id);
Geom createGeometry3D(Identifier id);
template<typename T>
Cons createConstraint3D(Identifier id, Geom first, Geom second, T constraint1);
void removeGeometry3D(Identifier id);
void removeConstraint3D(Identifier id);
using inheriter_base::removeGeometry3D;
using inheriter_base::removeConstraint3D;
bool hasGeometry3D(Identifier id);
Geom getGeometry3D(Identifier id);
bool hasConstraint3D(Identifier id);
Cons getConstraint3D(Identifier id);
};
struct inheriter : public mpl::if_<boost::is_same<Identifier, No_Identifier>, inheriter_base, inheriter_id>::type {};
struct math_prop {
typedef cluster_property kind;
typedef details::ClusterMath<Sys> type;
};
struct fix_prop {
typedef cluster_property kind;
typedef bool type;
};
struct vertex_prop {
typedef Geometry3D kind;
typedef GlobalVertex type;
};
struct edge_prop {
typedef Constraint3D kind;
typedef GlobalEdge type;
};
typedef mpl::vector6<vertex_prop, edge_prop, math_prop,
fix_prop, solverfailure, subsystemsolving> properties;
typedef mpl::vector2<Geometry3D, Constraint3D> objects;
typedef mpl::vector5<tag::point3D, tag::direction3D, tag::line3D, tag::plane3D, tag::cylinder3D> geometries;
typedef mpl::map0<> signals;
static void system_init(Sys& sys) {
sys.m_scheduler.addProcessJob(new SystemSolver());
};
static void system_copy(const Sys& from, Sys& into) {
//nothing to to as all objects and properties are copied with the clustergraph
};
};
};
namespace details {
//allow direct access to the stored geometry in a Geometry3D, copied from boost variant get
template <typename T>
struct get_visitor {
private:
typedef typename boost::add_pointer<T>::type pointer;
typedef typename boost::add_reference<T>::type reference;
public:
typedef pointer result_type;
public:
pointer operator()(reference operand) const {
return boost::addressof(operand);
}
template <typename U>
pointer operator()(const U&) const {
return static_cast<pointer>(0);
}
};
}
template<typename T, typename G>
typename boost::add_reference<T>::type get(G geom) {
typedef typename boost::add_pointer<T>::type T_ptr;
details::get_visitor<T> v;
T_ptr result = geom->apply(v);
//if (!result)
//TODO:throw bad_get();
return *result;
};
}//dcm
#include "imp/module_imp.hpp"
#endif //DCM_GEOMETRY3D_H

View File

@@ -1,409 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_PARALLEL_H
#define GCM_PARALLEL_H
#include <opendcm/core/constraint.hpp>
#include "geometry.hpp"
#include <boost/math/special_functions/fpclassify.hpp>
using boost::math::isfinite;
namespace dcm {
//the calculations( same as we always calculate directions we can outsource the work to this functions)
namespace orientation_detail {
template<typename Kernel, typename T1, typename T2>
inline typename Kernel::number_type calc(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const Direction& dir) {
switch(dir) {
case parallel:
if(d1.dot(d2) < 0)
return (d1+d2).norm();
case equal:
return (d1-d2).norm();
case opposite:
return (d1+d2).norm();
case perpendicular:
return d1.dot(d2);
default
:
assert(false);
}
return 0;
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline typename Kernel::number_type calcGradFirst(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& dd1,
const Direction& dir) {
typename Kernel::number_type res;
switch(dir) {
case parallel:
if(d1.dot(d2) < 0) {
res= ((d1+d2).dot(dd1) / (d1+d2).norm());
break;
}
case equal:
res = ((d1-d2).dot(dd1) / (d1-d2).norm());
break;
case opposite:
res= ((d1+d2).dot(dd1) / (d1+d2).norm());
break;
case perpendicular:
res = dd1.dot(d2);
break;
}
if(isfinite(res))
return res;
return 0;
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline typename Kernel::number_type calcGradSecond(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& dd2,
const Direction& dir) {
typename Kernel::number_type res;
switch(dir) {
case parallel:
if(d1.dot(d2) < 0) {
res = ((d1+d2).dot(dd2) / (d1+d2).norm());
break;
}
case equal:
res = ((d1-d2).dot(-dd2) / (d1-d2).norm());
break;
case opposite:
res = ((d1+d2).dot(dd2) / (d1+d2).norm());
break;
case perpendicular:
res = d1.dot(dd2);
break;
}
if((isfinite)(res))
return res;
return 0;
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline void calcGradFirstComp(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& grad,
const Direction& dir) {
switch(dir) {
case parallel:
if(d1.dot(d2) < 0) {
const_cast< E::MatrixBase<T3>& >(grad) = (d1+d2) / (d1+d2).norm();
return;
}
case equal:
const_cast< E::MatrixBase<T3>& >(grad) = (d1-d2) / (d1-d2).norm();
return;
case opposite:
const_cast< E::MatrixBase<T3>& >(grad) = (d1+d2) / (d1+d2).norm();
return;
case perpendicular:
const_cast< E::MatrixBase<T3>& >(grad) = d2;
return;
}
};
template<typename Kernel, typename T1, typename T2, typename T3>
inline void calcGradSecondComp(const E::MatrixBase<T1>& d1,
const E::MatrixBase<T2>& d2,
const E::MatrixBase<T3>& grad,
const Direction& dir) {
switch(dir) {
case parallel:
if(d1.dot(d2) < 0) {
const_cast< E::MatrixBase<T3>& >(grad) = (d2+d1) / (d1+d2).norm();
return;
}
case equal:
const_cast< E::MatrixBase<T3>& >(grad) = (d2-d1) / (d1-d2).norm();
return;
case opposite:
const_cast< E::MatrixBase<T3>& >(grad) = (d2+d1) / (d1+d2).norm();
return;
case perpendicular:
const_cast< E::MatrixBase<T3>& >(grad) = d1;
return;
}
};
}
template< typename Kernel >
struct Orientation::type< Kernel, tag::direction3D, tag::direction3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typename Orientation::options values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return orientation_detail::calc<Kernel>(param1, param2, fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1, param2, dparam1, fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1, param2, dparam2, fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1, param2, gradient, fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1, param2, gradient, fusion::at_key<Direction>(values).second);
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::line3D, tag::line3D > : public dcm::PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typename Orientation::options values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return orientation_detail::calc<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam1.template segment<3>(3),
fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam2.template segment<3>(3),
fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
fusion::at_key<Direction>(values).second);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
fusion::at_key<Direction>(values).second);
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::line3D, tag::plane3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
options values;
//makes it possible to allow only partial directions for derived constraints
inline dcm::Direction getValue() {
return fusion::at_key<Direction>(values).second;
};
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return orientation_detail::calc<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
getValue());
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return orientation_detail::calcGradFirst<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam1.template segment<3>(3),
getValue());
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return orientation_detail::calcGradSecond<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
dparam2.template segment<3>(3),
getValue());
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
getValue());
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
getValue());
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::line3D, tag::cylinder3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Orientation::type<Kernel, tag::line3D, tag::line3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::plane3D, tag::plane3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {};
template< typename Kernel >
struct Orientation::type< Kernel, tag::plane3D, tag::cylinder3D > : public Orientation::type<Kernel, tag::line3D, tag::plane3D> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
using Orientation::type<Kernel, tag::line3D, tag::plane3D>::values;
//template definition
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculate(param1, param2);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientFirst(param1, param2, dparam1);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
return Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientSecond(param1, param2, dparam2);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientFirstComplete(param1, param2, gradient);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
Orientation::type<Kernel, tag::line3D, tag::plane3D>::calculateGradientSecondComplete(param1, param2, gradient);
gradient(6)=0;
};
};
template< typename Kernel >
struct Orientation::type< Kernel, tag::cylinder3D, tag::cylinder3D > : public Orientation::type< Kernel, tag::line3D, tag::line3D > {
typedef typename Kernel::VectorMap Vector;
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradFirstComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
fusion::at_key<dcm::Direction>(Orientation::type< Kernel, tag::line3D, tag::line3D >::values).second);
gradient(6) = 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>().setZero();
orientation_detail::calcGradSecondComp<Kernel>(param1.template segment<3>(3),
param2.template segment<3>(3),
gradient.template segment<3>(3),
fusion::at_key<dcm::Direction>(Orientation::type< Kernel, tag::line3D, tag::line3D >::values).second);
gradient(6) = 0;
};
};
}
#endif

View File

@@ -1,121 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_SOLVER_3D_H
#define GCM_SOLVER_3D_H
#include "defines.hpp"
#include "opendcm/core/scheduler.hpp"
#include <boost/graph/depth_first_search.hpp>
namespace dcm {
namespace details {
template<typename Sys>
struct MES : public Sys::Kernel::MappedEquationSystem {
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef std::shared_ptr<Geometry3D> Geom;
typedef typename module3d::Constraint3D Constraint3D;
typedef std::shared_ptr<Constraint3D> Cons;
typedef typename module3d::math_prop math_prop;
typedef typename module3d::fix_prop fix_prop;
typedef typename Kernel::number_type Scalar;
typedef typename Sys::Kernel::MappedEquationSystem Base;
std::shared_ptr<Cluster> m_cluster;
#ifdef USE_LOGGING
dcm_logger log;
#endif
MES(std::shared_ptr<Cluster> cl, int par, int eqn);
virtual void recalculate();
virtual void removeLocalGradientZeros();
};
template<typename Sys>
struct SystemSolver : public Job<Sys> {
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
typedef typename system_traits<Sys>::template getModule<m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef std::shared_ptr<Geometry3D> Geom;
typedef typename module3d::Constraint3D Constraint3D;
typedef std::shared_ptr<Constraint3D> Cons;
typedef typename module3d::math_prop math_prop;
typedef typename module3d::fix_prop fix_prop;
typedef typename module3d::vertex_prop vertex_prop;
typedef MES<Sys> Mes;
#ifdef USE_LOGGING
src::logger log;
#endif
struct Rescaler {
std::shared_ptr<Cluster> cluster;
Mes& mes;
int rescales;
Rescaler(std::shared_ptr<Cluster> c, Mes& m);
void operator()();
Scalar calculateScale();
Scalar scaleClusters(Scalar sc);
void collectPseudoPoints(std::shared_ptr<Cluster> parent,
LocalVertex cluster,
std::vector<typename Kernel::Vector3,
Eigen::aligned_allocator<typename Kernel::Vector3> >& vec);
};
struct DummyScaler {
void operator()() {};
};
struct cycle_dedector:public boost::default_dfs_visitor {
bool& m_dedected;
cycle_dedector(bool& ed) : m_dedected(ed) {
m_dedected = false;
};
template <class Edge, class Graph>
void back_edge(Edge u, const Graph& g) {
m_dedected = true;
}
};
SystemSolver();
virtual void execute(Sys& sys);
void solveCluster(std::shared_ptr<Cluster> cluster, Sys& sys);
void finish(std::shared_ptr< Cluster > cluster, Sys& sys, Mes& mes);
};
}//details
}//dcm
#endif //DCM_SOLVER_3D_HPP

View File

@@ -1,196 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE3D_STATE_HPP
#define DCM_MODULE3D_STATE_HPP
#include <opendcm/moduleState/traits.hpp>
#include <opendcm/core/clustergraph.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <ios>
namespace karma = boost::spirit::karma;
namespace qi = boost::spirit::qi;
namespace dcm {
namespace details {
template<typename Sys>
struct getModule3D {
typedef typename system_traits<Sys>::template getModule<m3d>::type type;
};
}
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::Geometry3D , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::Geometry3D , System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry;
typedef karma::rule<iterator, std::shared_ptr<Geometry>(), karma::locals<int> > generator;
static void init(generator& r);
};
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::vertex_prop , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::vertex_prop , System, iterator > {
typedef karma::rule<iterator, GlobalVertex()> generator;
static void init(generator& r);
};
/*
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::math_prop , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::math_prop , System, iterator > {
typedef karma::rule<iterator, details::ClusterMath<System>&(), karma::locals<int> > generator;
static void init(generator& r);
};*/
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::Constraint3D , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::Constraint3D , System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry3D;
typedef typename details::getModule3D<System>::type::Constraint3D Constraint3D;
typedef typename details::getModule3D<System>::type::vertex_prop vertex_prop;
typedef typename details::getModule3D<System>::type::edge_prop edge_prop;
typedef karma::rule<iterator, std::shared_ptr<Constraint3D>()> generator;
static void init(generator& r);
};
template<typename System>
struct parser_generate< typename details::getModule3D<System>::type::edge_prop , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator< typename details::getModule3D<System>::type::edge_prop , System, iterator > {
typedef karma::rule<iterator, GlobalEdge&()> generator;
static void init(generator& r);
};
template<typename System>
struct parser_generate<typename details::getModule3D<System>::type::fix_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator<typename details::getModule3D<System>::type::fix_prop, System, iterator> {
typedef karma::rule<iterator, bool&()> generator;
static void init(generator& r);
};
/****************************************************************************************************/
/****************************************************************************************************/
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::Geometry3D , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::Geometry3D, System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D object_type;
typedef typename System::Kernel Kernel;
typedef qi::rule<iterator, std::shared_ptr<object_type>(System*), qi::space_type, qi::locals<std::string, typename Kernel::Vector, int> > parser;
static void init(parser& r);
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::vertex_prop, System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::vertex_prop, System, iterator > {
typedef qi::rule<iterator, GlobalVertex(), qi::space_type> parser;
static void init(parser& r);
};
/*
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::math_prop, System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::math_prop, System, iterator > {
typedef qi::rule<iterator, details::ClusterMath<System>(), qi::space_type > parser;
static void init(parser& r);
};*/
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::Constraint3D , System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::Constraint3D, System, iterator > {
typedef typename details::getModule3D<System>::type::Geometry3D Geometry3D;
typedef typename details::getModule3D<System>::type::Constraint3D Constraint3D;
typedef typename System::Kernel Kernel;
typedef qi::rule<iterator, std::shared_ptr<Constraint3D>(System*), qi::space_type > parser;
static void init(parser& r);
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::edge_prop, System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::edge_prop, System, iterator > {
typedef qi::rule<iterator, GlobalEdge(), qi::space_type> parser;
static void init(parser& r);
};
template<typename System>
struct parser_parse< typename details::getModule3D<System>::type::fix_prop, System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser< typename details::getModule3D<System>::type::fix_prop, System, iterator > {
typedef qi::rule<iterator, bool(), qi::space_type> parser;
static void init(parser& r);
};
}
#ifndef DCM_EXTERNAL_STATE
#include "imp/state_imp.hpp"
#endif
#endif //DCM_MODULE3D_STATE_HPP

View File

@@ -1,92 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GEOMETRY_PART_H
#define GCM_GEOMETRY_PART_H
#include <opendcm/core/geometry.hpp>
#include <opendcm/core/kernel.hpp>
namespace dcm {
namespace tag {
struct part {};
}
namespace modell {
struct quaternion_wxyz_vec3 {
/*Modell XYZ:
* 0 = w;
* 1 = x;
* 2 = y;
* 3 = z;
*/
template<typename Kernel, typename Accessor, typename Type>
void extract(Type& t, typename Kernel::Transform3D& trans) {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::Transform3D::Rotation Rotation;
typedef typename Kernel::Transform3D::Translation Translation;
Accessor a;
Rotation r;
r.w() = a.template get<Scalar, 0>(t);
r.x() = a.template get<Scalar, 1>(t);
r.y() = a.template get<Scalar, 2>(t);
r.z() = a.template get<Scalar, 3>(t);
Translation tr;;
tr.vector()(0) = a.template get<Scalar, 4>(t);
tr.vector()(1) = a.template get<Scalar, 5>(t);
tr.vector()(2) = a.template get<Scalar, 6>(t);
trans = r;
trans *= tr;
}
template<typename Kernel, typename Accessor, typename Type>
void inject(Type& t, typename Kernel::Transform3D& trans) {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::Transform3D::Rotation Rotation;
typedef typename Kernel::Transform3D::Translation Translation;
Accessor a;
const Rotation& r = trans.rotation();
a.template set<Scalar, 0>(r.w(), t);
a.template set<Scalar, 1>(r.x(), t);
a.template set<Scalar, 2>(r.y(), t);
a.template set<Scalar, 3>(r.z(), t);
const Translation& tr = trans.translation();
a.template set<Scalar, 4>(tr.vector()(0), t);
a.template set<Scalar, 5>(tr.vector()(1), t);
a.template set<Scalar, 6>(tr.vector()(2), t);
a.finalize(t);
};
};
}
}
#endif //GCM_GEOMETRY_PART_H

View File

@@ -1,659 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_MODULE_PART_H
#define GCM_MODULE_PART_H
#include "opendcm/core.hpp"
#include "opendcm/core/traits.hpp"
#include "opendcm/core/clustergraph.hpp"
#include "opendcm/core/property.hpp"
#include "opendcm/module3d.hpp"
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
namespace mpl = boost::mpl;
namespace dcm {
enum { clusterPart = 110};
enum CoordinateFrame {Local, Global};
template<typename Typelist, typename ID = No_Identifier>
struct ModulePart {
template<typename Sys>
struct type {
struct Part;
struct PrepareCluster;
struct EvaljuateCluster;
typedef std::shared_ptr<Part> Partptr;
typedef mpl::map2< mpl::pair<remove, boost::function<void (Partptr) > >,
mpl::pair<recalculated, boost::function<void (Partptr) > > > PartSignal;
typedef ID Identifier;
typedef mpl::map1<mpl::pair<recalculated, boost::function<void (std::shared_ptr<Sys>)> > > signals;
class Part_base : public Object<Sys, Part, PartSignal > {
protected:
#ifdef USE_LOGGING
dcm_logger log;
#endif
//check if we have module3d in this system
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
BOOST_MPL_ASSERT((mpl::not_<boost::is_same<module3d, mpl::void_> >));
//define what we need
typedef typename module3d::Geometry3D Geometry3D;
typedef std::shared_ptr<Geometry3D> Geom;
typedef typename boost::make_variant_over< Typelist >::type Variant;
typedef Object<Sys, Part, PartSignal> base;
typedef typename Sys::Kernel Kernel;
typedef typename Sys::Cluster Cluster;
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::Transform3D Transform;
struct cloner : boost::static_visitor<void> {
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
//visitor to write the calculated value into the variant
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(Transform& t) : m_transform(t) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<Kernel,
typename geometry_traits<T>::accessor >(t, m_transform);
}
Transform& m_transform;
};
//collect all clustergraph upstream cluster transforms
void transform_traverse(Transform& t, std::shared_ptr<Cluster> c);
public:
using Object<Sys, Part, PartSignal >::m_system;
template<typename T>
Part_base(const T& geometry, Sys& system, std::shared_ptr<Cluster> cluster);
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis);
template<typename T>
Geom addGeometry3D(const T& geom, CoordinateFrame frame = Global);
template<typename T>
void set(const T& geometry);
template<typename T>
T& get();
template<typename T>
T getGlobal();
virtual std::shared_ptr<Part> clone(Sys& newSys);
public:
Variant m_geometry;
Transform m_transform;
std::shared_ptr<Cluster> m_cluster;
void finishCalculation();
void fix(bool fix_value);
public:
//we hold a transform and need therefore a aligned new operator
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
struct Part_id : public Part_base {
template<typename T>
Part_id(const T& geometry, Sys& system, std::shared_ptr<typename Part_base::Cluster> cluster);
template<typename T>
typename Part_base::Geom addGeometry3D(const T& geom, Identifier id, CoordinateFrame frame = Global);
template<typename T>
void set(const T& geometry, Identifier id);
bool hasGeometry3D(Identifier id);
typename Part_base::Geom getGeometry3D(Identifier id);
Identifier& getIdentifier();
void setIdentifier(Identifier id);
};
struct Part : public mpl::if_<boost::is_same<Identifier, No_Identifier>, Part_base, Part_id>::type {
typedef typename mpl::if_<boost::is_same<Identifier, No_Identifier>, Part_base, Part_id>::type base;
template<typename T>
Part(const T& geometry, Sys& system, std::shared_ptr<typename base::Cluster> cluster);
friend struct PrepareCluster;
friend struct EvaljuateCluster;
public:
//we hold a transform and need therefore a aligned new operator
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
struct inheriter_base {
inheriter_base();
template<typename T>
Partptr createPart(const T& geometry);
void removePart(Partptr p);
template<typename T>
void setTransformation(const T& geom) {
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getProperty<typename module3d::math_prop>();
(typename geometry_traits<T>::modell()).template extract<typename Sys::Kernel,
typename geometry_traits<T>::accessor >(geom, cm.getTransform());
};
template<typename T>
T getTransformation() {
T geom;
getTransformation(geom);
return geom;
};
template<typename T>
void getTransformation(T& geom) {
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
details::ClusterMath<Sys>& cm = ((Sys*)this)->m_cluster->template getProperty<typename module3d::math_prop>();
(typename geometry_traits<T>::modell()).template inject<typename Sys::Kernel,
typename geometry_traits<T>::accessor >(geom, cm.getTransform());
};
//needed system functions
void system_sub(std::shared_ptr<Sys> subsys) {};
protected:
Sys* m_this;
//function object to emit remove signal too al geometry which is deleted by part deletion
struct remover {
typedef typename Sys::Cluster Cluster;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef std::shared_ptr<Geometry3D> Geom;
typedef typename module3d::Constraint3D Constraint3D;
typedef std::shared_ptr<Constraint3D> Cons;
Sys& system;
remover(Sys& s);
//see if we have a geometry or a constraint and emit the remove signal
void operator()(GlobalVertex v);
//we delete all global edges connecting to this part
void operator()(GlobalEdge e);
void operator()(std::shared_ptr<Cluster> g) {};
};
};
struct inheriter_id : public inheriter_base {
template<typename T>
Partptr createPart(const T& geometry, Identifier id);
bool hasPart(Identifier id);
Partptr getPart(Identifier id);
};
struct inheriter : public mpl::if_<boost::is_same<Identifier, No_Identifier>, inheriter_base, inheriter_id>::type {};
struct subsystem_property {
typedef Sys* type;
typedef cluster_property kind;
};
typedef mpl::vector1<subsystem_property> properties;
typedef mpl::vector1<Part> objects;
typedef mpl::vector0<> geometries;
struct PrepareCluster : public Job<Sys> {
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
PrepareCluster();
virtual void execute(Sys& sys);
};
struct EvaljuateCluster : public Job<Sys> {
typedef typename Sys::Cluster Cluster;
typedef typename Sys::Kernel Kernel;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
EvaljuateCluster();
virtual void execute(Sys& sys);
};
static void system_init(Sys& sys) {
sys.m_scheduler.addPreprocessJob(new PrepareCluster());
sys.m_scheduler.addPostprocessJob(new EvaljuateCluster());
};
static void system_copy(const Sys& from, Sys& into) {};
};
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
ModulePart<Typelist, ID>::type<Sys>::Part_base::Part_base(const T& geometry, Sys& system, std::shared_ptr<Cluster> cluster)
: Object<Sys, Part, PartSignal>(system), m_geometry(geometry), m_cluster(cluster) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Part3D"));
#endif
(typename geometry_traits<T>::modell()).template extract<Kernel,
typename geometry_traits<T>::accessor >(geometry, m_transform);
cluster->template setProperty<typename module3d::fix_prop>(false);
//the the clustermath transform
m_cluster->template getProperty<typename module3d::math_prop>().getTransform() = m_transform;
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, information) << "Init: "<<m_transform;
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Visitor>
typename Visitor::result_type ModulePart<Typelist, ID>::type<Sys>::Part_base::apply(Visitor& vis) {
return boost::apply_visitor(vis, m_geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Geom
ModulePart<Typelist, ID>::type<Sys>::Part_base::addGeometry3D(const T& geom, CoordinateFrame frame) {
Geom g(new Geometry3D(geom, *m_system));
if(frame == Local) {
//we need to collect all transforms up to this part!
Transform t;
transform_traverse(t, m_cluster);
g->transform(t);
}
fusion::vector<LocalVertex, GlobalVertex> res = m_cluster->addVertex();
m_cluster->template setObject<Geometry3D> (fusion::at_c<0> (res), g);
g->template setProperty<typename module3d::vertex_prop>(fusion::at_c<1>(res));
m_system->template objectVector<Geometry3D>().push_back(g);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::transform_traverse(typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Transform& t,
std::shared_ptr<typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Cluster> c) {
t *= c->template getProperty<typename Part_base::module3d::math_prop>().m_transform;
if(c->isRoot())
return;
transform_traverse(t, c->parent());
}
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::set(const T& geometry) {
Part_base::m_geometry = geometry;
(typename geometry_traits<T>::modell()).template extract<Kernel,
typename geometry_traits<T>::accessor >(geometry, Part_base::m_transform);
//set the clustermath transform
m_cluster->template getClusterProperty<typename module3d::math_prop>().getTransform() = m_transform;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
T& ModulePart<Typelist, ID>::type<Sys>::Part_base::get() {
return get<T>(this);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
T ModulePart<Typelist, ID>::type<Sys>::Part_base::getGlobal() {
//get the successive transform
Transform t;
transform_traverse(t, m_cluster);
//put it into the user type
T ut;
(typename geometry_traits<T>::modell()).template inject<Kernel,
typename geometry_traits<T>::accessor >(ut, t);
return ut;
};
template<typename Typelist, typename ID>
template<typename Sys>
std::shared_ptr<typename ModulePart<Typelist, ID>::template type<Sys>::Part>
ModulePart<Typelist, ID>::type<Sys>::Part_base::clone(Sys& newSys) {
//we need to reset the cluster pointer to the new system cluster
LocalVertex lv = Object<Sys, Part, PartSignal>::m_system->m_cluster->getClusterVertex(m_cluster);
GlobalVertex gv = Object<Sys, Part, PartSignal>::m_system->m_cluster->getGlobalVertex(lv);
std::shared_ptr<Part> np = Object<Sys, Part, PartSignal>::clone(newSys);
//there may be pointer inside the variant
cloner clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
fusion::vector<LocalVertex, std::shared_ptr<Cluster>, bool> res = newSys.m_cluster->getLocalVertexGraph(gv);
if(!fusion::at_c<2>(res)) {
//todo: throw
return np;
}
np->m_cluster = fusion::at_c<1>(res)->getVertexCluster(fusion::at_c<0>(res));
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::finishCalculation() {
m_transform.normalize();
apply_visitor vis(m_transform);
apply(vis);
#ifdef USE_LOGGING
BOOST_LOG_SEV(log, manipulation) << "New Value: "<<m_transform;
#endif
//emit the signal for new values
base::template emitSignal<recalculated>(((Part*)this)->shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::fix(bool fix_value) {
m_cluster->template setProperty<typename module3d::fix_prop>(fix_value);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
ModulePart<Typelist, ID>::type<Sys>::Part_id::Part_id(const T& geometry, Sys& system, std::shared_ptr<typename Part_base::Cluster> cluster)
: Part_base(geometry, system, cluster) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Geom
ModulePart<Typelist, ID>::type<Sys>::Part_id::addGeometry3D(const T& geom, Identifier id, CoordinateFrame frame) {
typename Part_base::Geom g = Part_base::addGeometry3D(geom, frame);
g->setIdentifier(id);
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
void ModulePart<Typelist, ID>::type<Sys>::Part_id::set(const T& geometry, Identifier id) {
Part_base::set(geometry);
setIdentifier(id);
};
template<typename Typelist, typename ID>
template<typename Sys>
bool ModulePart<Typelist, ID>::type<Sys>::Part_id::hasGeometry3D(Identifier id) {
typename Part_base::Geom g = Part_base::m_system->getGeometry3D(id);
if(!g)
return false;
//get the global vertex and check if it is a child of the part cluster
GlobalVertex v = g->template getProperty<typename Part_base::module3d::vertex_prop>();
return Part_base::m_cluster->getLocalVertex(v).second;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Geom
ModulePart<Typelist, ID>::type<Sys>::Part_id::getGeometry3D(Identifier id) {
return Part_base::m_system->getGeometry3D(id);
};
template<typename Typelist, typename ID>
template<typename Sys>
typename ModulePart<Typelist, ID>::template type<Sys>::Identifier&
ModulePart<Typelist, ID>::type<Sys>::Part_id::getIdentifier() {
return this->template getProperty<id_prop<Identifier> >();
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_id::setIdentifier(Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
ModulePart<Typelist, ID>::type<Sys>::Part::Part(const T& geometry, Sys& system, std::shared_ptr<typename base::Cluster> cluster)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Part_base, Part_id>::type(geometry, system, cluster) {
};
template<typename Typelist, typename ID>
template<typename Sys>
ModulePart<Typelist, ID>::type<Sys>::inheriter_base::inheriter_base() {
m_this = ((Sys*) this);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Partptr
ModulePart<Typelist, ID>::type<Sys>::inheriter_base::createPart(const T& geometry) {
typedef typename Sys::Cluster Cluster;
std::pair<std::shared_ptr<Cluster>, LocalVertex> res = m_this->m_cluster->createCluster();
Partptr p(new Part(geometry, * ((Sys*) this), res.first));
m_this->m_cluster->template setObject<Part> (res.second, p);
m_this->push_back(p);
res.first->template setProperty<type_prop>(clusterPart);
return p;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::inheriter_base::removePart(Partptr p) {
remover r(*m_this);
m_this->m_cluster->removeCluster(p->m_cluster, r);
p->template emitSignal<remove>(p);
m_this->erase(p);
};
template<typename Typelist, typename ID>
template<typename Sys>
ModulePart<Typelist, ID>::type<Sys>::inheriter_base::remover::remover(Sys& s) : system(s) {
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::inheriter_base::remover::operator()(GlobalVertex v) {
Geom g = system.m_cluster->template getObject<Geometry3D>(v);
if(g) {
g->template emitSignal<remove>(g);
system.erase(g);
}
Cons c = system.m_cluster->template getObject<Constraint3D>(v);
if(c) {
c->template emitSignal<remove>(c);
system.erase(c);
}
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::inheriter_base::remover::operator()(GlobalEdge e) {
Cons c = system.m_cluster->template getObject<Constraint3D>(e);
if(c) {
c->template emitSignal<remove>(c);
system.erase(c);
}
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Partptr
ModulePart<Typelist, ID>::type<Sys>::inheriter_id::createPart(const T& geometry, Identifier id) {
Partptr p = inheriter_base::createPart(geometry);
p->setIdentifier(id);
return p;
};
template<typename Typelist, typename ID>
template<typename Sys>
bool ModulePart<Typelist, ID>::type<Sys>::inheriter_id::hasPart(Identifier id) {
if(getPart(id))
return true;
return false;
};
template<typename Typelist, typename ID>
template<typename Sys>
typename ModulePart<Typelist, ID>::template type<Sys>::Partptr
ModulePart<Typelist, ID>::type<Sys>::inheriter_id::getPart(Identifier id) {
std::vector< Partptr >& vec = inheriter_base::m_this->template objectVector<Part>();
typedef typename std::vector<Partptr>::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return Partptr();
};
template<typename Typelist, typename ID>
template<typename Sys>
ModulePart<Typelist, ID>::type<Sys>::PrepareCluster::PrepareCluster() {
Job<Sys>::priority = 1000;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::PrepareCluster::execute(Sys& sys) {
//get all parts and set their values to the cluster's
typedef typename std::vector<Partptr>::iterator iter;
for(iter it = sys.template begin<Part>(); it != sys.template end<Part>(); it++) {
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getProperty<typename module3d::math_prop>();
cm.getTransform() = (*it)->m_transform;
};
};
template<typename Typelist, typename ID>
template<typename Sys>
ModulePart<Typelist, ID>::type<Sys>::EvaljuateCluster::EvaljuateCluster() {
Job<Sys>::priority = 1000;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::EvaljuateCluster::execute(Sys& sys) {
//get all parts and set their values to the cluster's
typedef typename std::vector<Partptr>::iterator iter;
for(iter it = sys.template begin<Part>(); it != sys.template end<Part>(); it++) {
details::ClusterMath<Sys>& cm = (*it)->m_cluster->template getProperty<typename module3d::math_prop>();
(*it)->m_transform = cm.getTransform();
(*it)->finishCalculation();
};
//get all subsystems and report their recalculation
typedef typename std::vector<std::shared_ptr<Sys> >::iterator siter;
for(siter it = sys.beginSubsystems(); it != sys.endSubsystems(); it++) {
(*it)->template emitSignal<recalculated>(*it);
};
};
}
#endif //GCM_MODULEPART_H

View File

@@ -1,40 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DEFINES_SHAPE3D_H
#define GCM_DEFINES_SHAPE3D_H
namespace dcm {
enum purpose {
startpoint = 1,
midpoint,
endpoint,
line,
circle
};
namespace details {
struct mshape3d {}; //base of modulehlg3d::type to allow other modules check for it
} //details
} //dcm
#endif

View File

@@ -1,138 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DISTANCE_SHAPE3D_H
#define GCM_DISTANCE_SHAPE3D_H
#include <opendcm/core/constraint.hpp>
#include <opendcm/moduleShape3d/geometry.hpp>
#include <math.h>
#include <Eigen/Dense>
#include <Eigen/Geometry>
namespace dcm {
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::segment3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef typename Kernel::Vector3 Vector3;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar sc_value, cross_n, cross_v12_n, v12_n;
typename Distance::options values;
Vector3 v01, v02, v12, cross;
#ifdef USE_LOGGING
dcm_logger log;
attrs::mutable_constant< std::string > tag;
type() : tag("Distance point3D segment3D") {
log.add_attribute("Tag", tag);
};
#endif
//template definition
void calculatePseudo(typename Kernel::Vector& point, Vec& v1, typename Kernel::Vector& segment, Vec& v2) {
Vector3 dir = (segment.template head<3>() - segment.template tail<3>()).normalized();
Vector3 pp = segment.head(3) + (segment.head(3)-point.head(3)).norm()*dir;
#ifdef USE_LOGGING
if(!boost::math::isnormal(pp.norm()))
BOOST_LOG_SEV(log, error) << "Unnormal pseudopoint detected";
#endif
v2.push_back(pp);
};
void setScale(Scalar scale) {
sc_value = fusion::at_key<double>(values).second*scale;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& point, const E::MatrixBase<DerivedB>& segment) {
//diff = point1 - point2
v01 = point-segment.template head<3>();
v02 = point-segment.template tail<3>();
v12 = segment.template head<3>() - segment.template tail<3>();
cross = v01.cross(v02);
v12_n = v12.norm();
cross_n = cross.norm();
cross_v12_n = cross_n/std::pow(v12_n,3);
const Scalar res = cross.norm()/v12_n - sc_value;
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal residual detected: "<<res;
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
const E::MatrixBase<DerivedC>& dpoint) {
const Vector3 d_point = dpoint; //eigen only acceppts vector3 for cross product
const Vector3 d_cross = d_point.cross(v02) + v01.cross(d_point);
const Scalar res = cross.dot(d_cross)/(cross_n*v12_n);
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal first cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", segment: "<<segment.transpose()
<<" and dpoint: "<<dpoint.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
const E::MatrixBase<DerivedC>& dsegment) {
const Vector3 d_cross = - (dsegment.template head<3>().cross(v02) + v01.cross(dsegment.template tail<3>()));
const Vector3 d_v12 = dsegment.template head<3>() - dsegment.template tail<3>();
const Scalar res = cross.dot(d_cross)/(cross_n*v12_n) - v12.dot(d_v12)*cross_v12_n;
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG_SEV(log, error) << "Unnormal second cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", segment: "<<segment.transpose()
<< "and dsegment: "<<dsegment.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
E::MatrixBase<DerivedC>& gradient) {
//gradient = (v02.cross(cross)+cross.cross(v01))/(cross.norm()*v12_n);
gradient = (v02-v01).cross(cross)/(cross_n*v12_n);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>() = cross.cross(v02)/(cross_n*v12_n) - v12*cross_v12_n;
gradient.template tail<3>() = v01.cross(cross)/(cross_n*v12_n) + v12*cross_v12_n;
};
};
}
#endif //GCM_DISTANCE_SHAPE3D_H

View File

@@ -1,91 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_FIXED_SHAPE3D_H
#define GCM_FIXED_SHAPE3D_H
//we need constraints to identify connections between geometries in our shapes, however, if the
//geometries are linked to each other a calculation is not necessary. Therefore a no-equation constraint
//is needed
#include <opendcm/core/equations.hpp>
namespace dcm {
namespace details {
//this equation is for internal use only. one needs to ensure the constraint is disabled after adding
//this fixed equation
struct Fixed : public Equation<Orientation, Direction, true> {
using Equation::options;
Fixed() : Equation() {
setDefault();
};
void setDefault() {};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typename Fixed::options values;
//we shall not use this equation, warn the user about wrong usage
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
static Fixed fixed;
}//details
} //dcm
#endif

View File

@@ -1,242 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GENERATOR_SHAPE3D_H
#define GCM_GENERATOR_SHAPE3D_H
#include <opendcm/core/defines.hpp>
#include <opendcm/core/geometry.hpp>
#include <opendcm/module3d/defines.hpp>
#include "geometry.hpp"
#include "fixed.hpp"
#include "defines.hpp"
#include <boost/exception/errinfo_errno.hpp>
#include <boost_bind_bind.hpp>
namespace bp = boost::placeholders;
namespace dcm {
namespace details {
template<typename Sys>
struct ShapeGeneratorBase {
BOOST_MPL_ASSERT((typename system_traits<Sys>::template getModule<details::m3d>::has_module));
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef typename module3d::Constraint3D Constraint3D;
typedef typename system_traits<Sys>::template getModule<details::mshape3d>::type moduleShape3d;
typedef typename moduleShape3d::Shape3D Shape3D;
typedef typename Shape3D::ShapeVector ShapeVector;
typedef typename Shape3D::GeometryVector GeometryVector;
typedef typename Shape3D::ConstraintVector ConstraintVector;
typedef typename moduleShape3d::shape_purpose_prop shape_purpose_prop;
typedef typename moduleShape3d::shape_geometry_prop shape_geometry_prop;
typedef typename moduleShape3d::shape_constraint_prop shape_constraint_prop;
Sys* m_system;
std::shared_ptr<Shape3D> m_shape;
GeometryVector* m_geometries;
ShapeVector* m_shapes;
ConstraintVector* m_constraints;
ShapeGeneratorBase(Sys* system) : m_system(system) {};
virtual ~ShapeGeneratorBase() {};
void set(std::shared_ptr<Shape3D> shape,
GeometryVector* geometries,
ShapeVector* shapes,
ConstraintVector* constraints) {
m_shape = shape;
m_geometries = geometries;
m_shapes = shapes;
m_constraints = constraints;
};
//check if all needed parts are supplied
virtual bool check() = 0;
//initialise all relations between the geometries
virtual void init() = 0;
//get geometry3d for optional types (e.g. midpoints)
virtual std::shared_ptr<Geometry3D> getOrCreateG3d(int type) = 0;
//get hlgeometry3d for optional types
virtual std::shared_ptr<Shape3D> getOrCreateHLG3d(int type) = 0;
//append needs to be on this base class as the shape appends are protected
void append(std::shared_ptr<Geometry3D> g) {
m_shape->append(g);
};
void append(std::shared_ptr<Shape3D> g) {
m_shape->append(g);
};
void append(std::shared_ptr<Constraint3D> g) {
m_shape->append(g);
};
};
} //details
struct dummy_generator {
template<typename Sys>
struct type : public details::ShapeGeneratorBase<Sys> {
type(Sys* system) : details::ShapeGeneratorBase<Sys>(system) {};
//check if all needed parts are supplied
virtual bool check() {
throw creation_error() << boost::errinfo_errno(210) << error_message("not all needd types for high level geometry present");
};
//initialise all relations between the geometries, throw on error
virtual void init() {
throw creation_error() << boost::errinfo_errno(211) << error_message("dummy generator can't create high level geometry");
};
//get geometry3d for optional types (e.g. midpoints)
virtual std::shared_ptr<typename details::ShapeGeneratorBase<Sys>::Geometry3D> getOrCreateG3d(int type) {
throw creation_error() << boost::errinfo_errno(212) << error_message("dummy generator has no geometry to access");
};
//get hlgeometry3d for optional types
virtual std::shared_ptr<typename details::ShapeGeneratorBase<Sys>::Shape3D> getOrCreateHLG3d(int type) {
throw creation_error() << boost::errinfo_errno(213) << error_message("dummy generator has no high level geometry to access");
};
};
};
//test generator
struct segment3D {
template<typename Sys>
struct type : public dcm::details::ShapeGeneratorBase<Sys> {
typedef dcm::details::ShapeGeneratorBase<Sys> base;
typedef typename Sys::Kernel Kernel;
using typename base::Geometry3D;
using typename base::Constraint3D;
using typename base::Shape3D;
type(Sys* system) : details::ShapeGeneratorBase<Sys>(system) {};
//check if all needed parts are supplied, a segment needs 2 points
virtual bool check() {
//even we have a real geometry segment
if(base::m_shape->getGeometryType() == tag::weight::segment::value)
return true;
//or two point geometries
if(base::m_geometries->size() == 2)
return true;
return false;
};
//initialise all relations between the geometries
virtual void init() {
if(base::m_shape->getGeometryType() == dcm::tag::weight::segment::value) {
//link the line geometry to our shape
std::shared_ptr<Geometry3D> g1 = base::m_system->createGeometry3D();
base::append(g1);
g1->template linkTo<tag::segment3D>(base::m_shape,0);
g1->template setProperty<typename base::shape_purpose_prop>(line);
g1->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, bp::_1));
//we have a segment, lets link the two points to it
std::shared_ptr<Geometry3D> g2 = base::m_system->createGeometry3D();
base::append(g2);
g2->template setProperty<typename base::shape_purpose_prop>(startpoint);
std::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::append(g3);
g3->template setProperty<typename base::shape_purpose_prop>(endpoint);
//link the points to our new segment
g2->template linkTo<tag::point3D>(base::m_shape, 0);
g3->template linkTo<tag::point3D>(base::m_shape, 3);
//add the fix constraints
std::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g2, details::fixed);
std::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
base::append(c1);
c2->disable(); //required by fixed constraint
base::append(c2);
}
else if(base::m_geometries->size() == 2) {
//we have two points, lets get them
std::shared_ptr<Geometry3D> g1 = fusion::at_c<0>(base::m_geometries->operator[](0));
std::shared_ptr<Geometry3D> g2 = fusion::at_c<0>(base::m_geometries->operator[](1));
//possibility 1: two points. we add a segment line an link the point in
if(g1->getGeometryType() == tag::weight::point::value || g2->getGeometryType() == tag::weight::point::value) {
g1->template setProperty<typename base::shape_purpose_prop>(startpoint);
g2->template setProperty<typename base::shape_purpose_prop>(endpoint);
//construct our segment value
typename Kernel::Vector val(6);
val.head(3) = g1->getValue();
val.tail(3) = g2->getValue();
//the shape is a segment
base::m_shape->template setValue<tag::segment3D>(val);
//and create a segment geometry we use as line
std::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::append(g3);
g3->template linkTo<tag::segment3D>(base::m_shape,0);
g3->template setProperty<typename base::shape_purpose_prop>(line);
g3->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, bp::_1));
//link the points to our new segment
g1->template linkTo<tag::point3D>(base::m_shape, 0);
g2->template linkTo<tag::point3D>(base::m_shape, 3);
//add the fix constraints to show our relation
std::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g3, details::fixed);
std::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
base::append(c1);
c2->disable(); //required by fixed constraint
base::append(c2);
}
else
throw creation_error() << boost::errinfo_errno(501) << error_message("Wrong geometries for segment construction");
};
};
//get geometry3d for optional types (e.g. midpoints)
virtual std::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Geometry3D> getOrCreateG3d(int type) {
return std::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Geometry3D>();
};
//get hlgeometry3d for optional types
virtual std::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Shape3D> getOrCreateHLG3d(int type) {
return std::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Shape3D>();
};
};
};
} //dcm
#endif //GCM_GENERATOR_SHAPE3D_H

View File

@@ -1,45 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GEOMETRY_SHAPE3D_H
#define DCM_GEOMETRY_SHAPE3D_H
#include "opendcm/core/geometry.hpp"
#include "opendcm/module3d/geometry.hpp"
namespace dcm {
namespace details {
template<typename T>
struct tag_traits {
typedef void return_type;
typedef void value_type;
BOOST_MPL_ASSERT_MSG(false, NO_TAG_TRAITS_SPECIFIED_FOR_TYPE, (T));
};
} //details
namespace tag {
struct segment3D : details::stacked2_geometry<weight::segment, point3D, point3D> {};
} //tag
} //dcm
#endif

View File

@@ -1,851 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_MODULE_SHAPE3D_H
#define GCM_MODULE_SHAPE3D_H
#include <opendcm/core.hpp>
#include <opendcm/core/geometry.hpp>
#include <opendcm/module3d.hpp>
#include "defines.hpp"
#include "geometry.hpp"
#include "generator.hpp"
#include <boost/mpl/if.hpp>
#include <boost/mpl/map.hpp>
#include <boost/type_traits.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define APPEND_SINGLE(z, n, data) \
typedef typename Sys::Identifier Identifier; \
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::geometry_types gtypes; \
typedef typename system_traits<Sys>::template getModule<details::mshape3d>::type::geometry_types stypes; \
g_ptr = details::converter_g<BOOST_PP_CAT(Arg,n), Geometry3D>::template apply<gtypes, Sys, Identifier>(BOOST_PP_CAT(arg,n), m_this); \
if(!g_ptr) { \
hlg_ptr = details::converter_hlg<BOOST_PP_CAT(Arg,n), Shape3D>::template apply<stypes, Sys, Identifier>(BOOST_PP_CAT(arg,n), data, m_this); \
if(!hlg_ptr) \
throw creation_error() << boost::errinfo_errno(216) << error_message("could not handle input"); \
else \
data->append(hlg_ptr);\
} \
else { \
data->append(g_ptr); \
} \
#define CREATE_DEF(z, n, data) \
template < \
typename Generator \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg) \
> \
std::shared_ptr<Shape3D> createShape3D( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
);
#define CREATE_DEC(z, n, data) \
template<typename TypeList, typename ID> \
template<typename Sys> \
template <\
typename Generator \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg)\
> \
std::shared_ptr<typename ModuleShape3D<TypeList, ID>::template type<Sys>::Shape3D> \
ModuleShape3D<TypeList, ID>::type<Sys>::inheriter_base::createShape3D( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
{ \
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d; \
typedef typename module3d::Geometry3D Geometry3D; \
std::shared_ptr<Geometry3D> g_ptr; \
std::shared_ptr<Shape3D> hlg_ptr; \
std::shared_ptr<Shape3D> ptr = std::shared_ptr<Shape3D>(new Shape3D(*m_this)); \
BOOST_PP_REPEAT(n, APPEND_SINGLE, ptr) \
ptr->template initShape<Generator>();\
m_this->push_back(ptr);\
return ptr;\
};
namespace mpl = boost::mpl;
namespace dcm {
namespace details {
//return always a geometry3d pointer struct, no matter what's the supplied type
template<typename T, typename R>
struct converter_g {
//check if the type T is usable from within module3d, as it could also be a shape type
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
mpl::and_<
mpl::not_< boost::is_same<typename mpl::find<gtypes, T>::type,typename mpl::end<gtypes>::type> >,
mpl::not_<boost::is_same<Identifier, T> >
>, std::shared_ptr<R> >::type apply(T const& t, Sys* sys) {
return sys->createGeometry3D(t);
};
//seems to be a shape type, return an empty geometry
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
mpl::and_<
boost::is_same<typename mpl::find<gtypes, T>::type, typename mpl::end<gtypes>::type>,
mpl::not_<boost::is_same<Identifier, T> >
>, std::shared_ptr<R> >::type apply(T const& t, Sys* sys) {
return std::shared_ptr<R>();
};
//seems to be an identifier type, lets check if we have such a geometry
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
boost::is_same<Identifier, T>, std::shared_ptr<R> >::type apply(T const& t, Sys* sys) {
return sys->getGeometry3D(t);
};
};
template<typename R>
struct converter_g< std::shared_ptr<R>, R> {
template<typename gtypes, typename Sys, typename Identifier>
static std::shared_ptr<R> apply(std::shared_ptr<R> t, Sys* sys) {
return t;
};
};
template<typename T, typename R>
struct converter_hlg {
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
mpl::and_<
boost::is_same<typename mpl::find<gtypes, T>::type, typename mpl::end<gtypes>::type>,
mpl::not_<boost::is_same<Identifier, T> >
>,
std::shared_ptr<R> >::type apply(T const& t, std::shared_ptr<R> self, Sys* sys) {
return std::shared_ptr<R>();
};
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
mpl::not_< boost::is_same<typename mpl::find<gtypes, T>::type, typename mpl::end<gtypes>::type> >,
std::shared_ptr<R> >::type apply(T const& t, std::shared_ptr<R> self, Sys* sys) {
//shape can only be set one time, throw an error otherwise
if(self->holdsType())
throw creation_error() << boost::errinfo_errno(410) << error_message("Shape can only be set with one geometry");
self->set(t);
return self;
};
//seems to be an identifier type, lets check if we have such a geometry
template<typename gtypes, typename Sys, typename Identifier>
static typename boost::enable_if<
boost::is_same<Identifier, T>, std::shared_ptr<R> >::type apply(T const& t, std::shared_ptr<R> self, Sys* sys) {
return sys->getShape3D(t);
};
};
template<typename R>
struct converter_hlg<std::shared_ptr<R>, R> {
template<typename gtypes, typename Sys, typename Identifier>
static std::shared_ptr<R> apply(std::shared_ptr<R> t, std::shared_ptr<R> self, Sys* sys) {
return t;
};
};
}//details
template<typename TypeList, typename ID = No_Identifier>
struct ModuleShape3D {
template<typename Sys>
struct type : details::mshape3d {
typedef TypeList geometry_types;
//forward declare
struct inheriter_base;
struct Shape3D;
typedef mpl::map2<
mpl::pair<remove, boost::function<void (std::shared_ptr<Shape3D>) > >,
mpl::pair<remove, boost::function<void (std::shared_ptr<Shape3D>) > > > ShapeSig;
template<typename Derived>
struct Shape3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>, public Object<Sys, Derived, ShapeSig > {
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
//traits are only accessible in subclass scope
BOOST_MPL_ASSERT((typename system_traits<Sys>::template getModule<details::m3d>::has_module));
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef typename module3d::Constraint3D Constraint3D;
Shape3D_base(Sys& system);
template<typename T>
Shape3D_base(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry);
bool holdsType() {
return m_geometry.which()!=0;
};
int whichType() {
return m_geometry.which()-1;
};
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis) {
return boost::apply_visitor(vis, m_geometry);
};
template<typename T>
T convertTo() {
T t;
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, Base::m_global);
return t;
};
virtual std::shared_ptr<Derived> clone(Sys& newSys);
/*shape access functions and extractors to mimic vector<> iterators*/
typedef std::vector<fusion::vector<std::shared_ptr<Geometry3D>, Connection> > GeometryVector;
typedef std::vector<fusion::vector<std::shared_ptr<Derived>, Connection> > ShapeVector;
typedef std::vector<fusion::vector<std::shared_ptr<Constraint3D>, Connection> > ConstraintVector;
struct geom_extractor {
typedef std::shared_ptr<Geometry3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
struct shape_extractor {
typedef std::shared_ptr<Shape3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
struct cons_extractor {
typedef std::shared_ptr<Constraint3D> result_type;
template<typename T>
result_type operator()(T& pair) const {
return fusion::at_c<0>(pair);
};
};
typedef boost::transform_iterator<geom_extractor, typename GeometryVector::const_iterator> geometry3d_iterator;
typedef boost::transform_iterator<shape_extractor, typename ShapeVector::iterator > shape3d_iterator;
typedef boost::transform_iterator<cons_extractor, typename ConstraintVector::iterator > constraint3d_iterator;
shape3d_iterator beginShape3D() {
return boost::make_transform_iterator(m_shapes.begin(), shape_extractor());
};
shape3d_iterator endShape3D() {
return boost::make_transform_iterator(m_shapes.end(), shape_extractor());
};
geometry3d_iterator beginGeometry3D() {
return boost::make_transform_iterator(m_geometries.begin(), geom_extractor());
};
geometry3d_iterator endGeometry3D() {
return boost::make_transform_iterator(m_geometries.end(), geom_extractor());
};
constraint3d_iterator beginConstraint3D() {
return boost::make_transform_iterator(m_constraints.begin(), cons_extractor());
};
constraint3d_iterator endConstraint3D() {
return boost::make_transform_iterator(m_constraints.end(), cons_extractor());
};
std::shared_ptr<Geometry3D> geometry(purpose f);
template<typename T>
std::shared_ptr<Shape3D> subshape();
//callbacks
void recalc(std::shared_ptr<Geometry3D> g);
void remove(std::shared_ptr<Geometry3D> g);
void remove(std::shared_ptr<Derived> g);
void remove(std::shared_ptr<Constraint3D> g);
private:
//we store all geometries, shapes and constraint which belong to this shape.
//Furthermore we store the remove connections, as we need to disconnect them later
GeometryVector m_geometries;
ShapeVector m_shapes;
ConstraintVector m_constraints;
protected:
#ifdef USE_LOGGING
src::logger log;
#endif
typedef details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries> Base;
typedef Object<Sys, Derived, ShapeSig > ObjBase;
typedef typename mpl::push_front<TypeList, boost::blank>::type ExtTypeList;
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
struct cloner : boost::static_visitor<void> {
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
//visitor to write the calculated value into the variant
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(typename Kernel::Vector& v) : value(v) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, value);
}
typename Kernel::Vector& value;
};
Variant m_geometry; //Variant holding the real geometry type
std::shared_ptr< details::ShapeGeneratorBase<Sys> > m_generator;
using Object<Sys, Derived, ShapeSig>::m_system;
template<typename generator>
void initShape() {
m_generator = std::shared_ptr<details::ShapeGeneratorBase<Sys> >(new typename generator::template type<Sys>(m_system));
m_generator->set(ObjBase::shared_from_this(), &m_geometries, &m_shapes, &m_constraints);
if(!m_generator->check())
throw creation_error() << boost::errinfo_errno(210) << error_message("not all needd geometry for shape present");
m_generator->init();
};
//disconnect all remove signals of stored geometry/shapes/constraints
void disconnectAll();
//the storage is private, all things need to be added by this methods.
//this is used to ensure the proper event connections
std::shared_ptr<Derived> append(std::shared_ptr<Geometry3D> g);
std::shared_ptr<Derived> append(std::shared_ptr<Derived> g);
std::shared_ptr<Derived> append(std::shared_ptr<Constraint3D> g);
//override protected event functions to emit signals
void reset() {};
void recalculated() {};
void removed() {};
friend struct inheriter_base;
friend struct Object<Sys, Derived, mpl::map0<> >;
};
template<typename Derived>
class Shape3D_id : public Shape3D_base<Derived> {
typedef Shape3D_base<Derived> Base;
#ifdef USE_LOGGING
attrs::mutable_constant< std::string > log_id;
#endif
public:
Shape3D_id(Sys& system);
template<typename T>
Shape3D_id(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry, ID id);
//somehow the base class set function is not found
template<typename T>
void set(const T& geometry);
ID& getIdentifier();
void setIdentifier(ID id);
};
struct Shape3D : public mpl::if_<boost::is_same<ID, No_Identifier>,
Shape3D_base<Shape3D>, Shape3D_id<Shape3D> >::type {
Shape3D(Sys& system);
template<typename T>
Shape3D(const T& geometry, Sys& system);
//allow accessing the internals by module3d classes but not by users
friend struct details::ClusterMath<Sys>;
friend struct details::ClusterMath<Sys>::map_downstream;
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct inheriter_base;
friend struct details::ShapeGeneratorBase<Sys>;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//inheriter for own functions
struct inheriter_base {
inheriter_base() {
m_this = (Sys*)this;
};
void system_sub(std::shared_ptr<Sys> subsys) {};
protected:
Sys* m_this;
public:
//with no vararg templates before c++11 we need preprocessor to create the overloads of create we need
BOOST_PP_REPEAT(5, CREATE_DEF, ~)
void removeShape3D(std::shared_ptr<Shape3D> g);
};
struct inheriter_id : public inheriter_base {
//we don't have a createshape3d method with identifier, as identifiers can be used to
//specifie creation geometries or shapes. Therefore a call would always be ambiguous.
void removeShape3D(ID id);
bool hasShape3D(ID id);
std::shared_ptr<Shape3D> getShape3D(ID id);
using inheriter_base::removeShape3D;
protected:
using inheriter_base::m_this;
};
struct inheriter : public mpl::if_<boost::is_same<ID, No_Identifier>, inheriter_base, inheriter_id>::type {};
//add properties to geometry and constraint to evaluate their shape partipance
struct shape_purpose_prop {
typedef purpose type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D kind;
};
struct shape_geometry_prop {
typedef bool type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D kind;
};
struct shape_constraint_prop {
typedef bool type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Constraint3D kind;
};
//needed typedefs
typedef ID Identifier;
typedef mpl::vector3<shape_purpose_prop, shape_constraint_prop, shape_geometry_prop> properties;
typedef mpl::vector1<Shape3D> objects;
typedef mpl::vector1<tag::segment3D> geometries;
typedef mpl::map0<> signals;
//needed static functions
static void system_init(Sys& sys) {};
static void system_copy(const Sys& from, Sys& into) {};
};
};
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
BOOST_PP_REPEAT(5, CREATE_DEC, ~)
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::Shape3D_base(Sys& system)
: Object<Sys, Derived, ShapeSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::Shape3D_base(const T& geometry, Sys& system)
: Object<Sys, Derived, ShapeSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::set(const T& geometry) {
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
this->template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, this->getValue());
reset();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived> ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::clone(Sys& newSys) {
//copy the standard stuff
std::shared_ptr<Derived> np = std::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//it's possible that the variant contains pointers, so we need to clone them
cloner clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::geometry(purpose f) {
for(geometry3d_iterator it = beginGeometry3D(); it != endGeometry3D(); it++) {
if((*it)->template getProperty<shape_purpose_prop>() == f)
return *it;
};
return std::shared_ptr<Geometry3D>();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(std::shared_ptr<Geometry3D> g) {
g->template setProperty<shape_geometry_prop>(true);
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(std::shared_ptr<Geometry3D>)>(&Shape3D_base::remove) , this, _1));
m_geometries.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(std::shared_ptr<Derived> g) {
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(std::shared_ptr<Derived>)>(&Shape3D_base::remove) , this, _1));
m_shapes.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
std::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(std::shared_ptr<Constraint3D> g) {
Connection c = g->template connectSignal<dcm::remove>(boost::bind(static_cast<void (Shape3D_base::*)(std::shared_ptr<Constraint3D>)>(&Shape3D_base::remove) , this, _1));
m_constraints.push_back(fusion::make_vector(g,c));
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::disconnectAll() {
typename GeometryVector::iterator git;
for(git = m_geometries.begin(); git!=m_geometries.end(); git++)
fusion::at_c<0>(*git)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*git));
typename ShapeVector::iterator sit;
for(sit = m_shapes.begin(); sit!=m_shapes.end(); sit++)
fusion::at_c<0>(*sit)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*sit));
typename ConstraintVector::iterator cit;
for(cit = m_constraints.begin(); cit!=m_constraints.end(); cit++)
fusion::at_c<0>(*cit)->template disconnectSignal<dcm::remove>(fusion::at_c<1>(*cit));
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::recalc(std::shared_ptr<Geometry3D> g) {
//we recalculated thebase line, that means we have our new value. use it.
Base::finishCalculation();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(std::shared_ptr<Geometry3D> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinite recursion
//get the vector object where the geometry is part of
typename GeometryVector::const_iterator it;
for(it=m_geometries.begin(); it!=m_geometries.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_geometries.erase(std::remove(m_geometries.begin(), m_geometries.end(), *it), m_geometries.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(std::shared_ptr<Derived> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinite recursion
//get the vector object where the geometry is part of
typename ShapeVector::const_iterator it;
for(it=m_shapes.begin(); it!=m_shapes.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_shapes.erase(std::remove(m_shapes.begin(), m_shapes.end(), *it), m_shapes.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::remove(std::shared_ptr<Constraint3D> g) {
//before we delete this shape by calling the system remove function, we need to remove
//this geometry as this would be deleted again by the system call and we would go into infinite recursion
//get the vector object where the geometry is part of
typename ConstraintVector::const_iterator it;
for(it=m_constraints.begin(); it!=m_constraints.end(); it++) {
if(fusion::at_c<0>(*it)==g)
break;
};
m_constraints.erase(std::remove(m_constraints.begin(), m_constraints.end(), *it), m_constraints.end());
ObjBase::m_system->removeShape3D(ObjBase::shared_from_this());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::Shape3D_id(Sys& system)
: ModuleShape3D<Typelist, ID>::template type<Sys>::template Shape3D_base<Derived>(system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::Shape3D_id(const T& geometry, Sys& system)
: ModuleShape3D<Typelist, ID>::template type<Sys>::template Shape3D_base<Derived>(geometry, system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::set(const T& geometry, Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::set(const T& geometry) {
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
typename ModuleShape3D<Typelist, ID>::template type<Sys>::Identifier&
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::getIdentifier() {
return this->template getProperty<id_prop<Identifier> >();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::setIdentifier(Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
#ifdef USE_LOGGING
std::stringstream str;
str<<this->template getProperty<id_prop<Identifier> >();
log_id.set(str.str());
BOOST_LOG(Base::log)<<"Identifyer set: "<<id;
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D::Shape3D(Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Shape3D_base<Shape3D>,
Shape3D_id<Shape3D> >::type(system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D::Shape3D(const T& geometry, Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Shape3D_base<Shape3D>,
Shape3D_id<Shape3D> >::type(geometry, system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_base::removeShape3D(std::shared_ptr<Shape3D> g) {
//disconnect all shapes, geometries and constraints, as otherwise we would go into infinite
//recursion
g->disconnectAll();
//remove all constraints is unnecessary as they get removed together with the geometries
//remove all geometries
typedef typename Shape3D::geometry3d_iterator git;
for(git it=g->beginGeometry3D(); it!=g->endGeometry3D(); it++)
m_this->removeGeometry3D(*it);
/* TODO: find out why it iterates over a empty vector and crashes...
//remove all subshapes
typedef typename Shape3D::shape3d_iterator sit;
for(sit it=g->beginShape3D(); it!=g->endShape3D(); it++) {
m_this->removeShape3D(*it);
};*/
//emit remove shape signal before actually deleting it
g->template emitSignal<remove>(g);
m_this->erase(g);
};
template<typename Typelist, typename ID>
template<typename Sys>
bool ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_id::hasShape3D(Identifier id) {
if(getShape3D(id))
return true;
return false;
};
template<typename Typelist, typename ID>
template<typename Sys>
std::shared_ptr<typename ModuleShape3D<Typelist, ID>::template type<Sys>::Shape3D>
ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_id::getShape3D(Identifier id) {
std::vector< std::shared_ptr<Shape3D> >& vec = inheriter_base::m_this->template objectVector<Shape3D>();
typedef typename std::vector< std::shared_ptr<Shape3D> >::iterator iter;
for(iter it=vec.begin(); it!=vec.end(); it++) {
if(compare_traits<Identifier>::compare((*it)->getIdentifier(), id))
return *it;
};
return std::shared_ptr<Shape3D>();
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModuleShape3D<Typelist, ID>::type<Sys>::inheriter_id::removeShape3D(Identifier id) {
std::shared_ptr<Shape3D> s = getShape3D(id);
if(s)
removeShape3D(s);
};
}//dcm
#endif //GCM_MODULE_SHAPE3D_H

View File

@@ -1,69 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_DEFINES_STATE_H
#define DCM_DEFINES_STATE_H
#include "opendcm/core/property.hpp"
#include "opendcm/core/clustergraph.hpp"
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
namespace dcm {
namespace details {
struct cluster_vertex_prop {
typedef GlobalVertex type;
typedef cluster_property kind;
};
}
}
BOOST_FUSION_ADAPT_TPL_STRUCT(
(T1)(T2)(T3)(T4),
(dcm::ClusterGraph) (T1)(T2)(T3)(T4),
(int, test)
(typename dcm::details::pts<T3>::type, m_properties))
//fusion adopt struct needs to avoid commas for type definition, as this breaks the macro syntax.
//we use this ugly nested struct to declare the dcm system from template parameters without commas
template<typename T1>
struct t1 {
template<typename T2>
struct t2 {
template<typename T3>
struct t3 {
template<typename T4>
struct t4 {
typedef dcm::System<T1,T2,T3,T4> type;
};
};
};
};
BOOST_FUSION_ADAPT_TPL_STRUCT(
(Kernel)(M1)(M2)(M3),
(dcm::System)(Kernel)(M1)(M2)(M3),
(typename t1<Kernel>::template t2<M1>::template t3<M2>::template t4<M3>::type::OptionOwner::Properties, m_options->m_properties)
(typename Kernel::Properties, m_kernel.m_properties)
(std::shared_ptr<typename t1<Kernel>::template t2<M1>::template t3<M2>::template t4<M3>::type::Cluster>, m_cluster)
)
#endif

View File

@@ -1,75 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_GENERATOR_H
#define DCM_EDGE_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_generator.hpp"
#include "object_generator.hpp"
#include "extractor.hpp"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/include/is_sequence.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace dcm {
namespace details {
template<typename Sys>
struct edge_generator : karma::grammar<Iterator, std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >()> {
edge_generator();
karma::rule<Iterator, std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >()> edge_range;
karma::rule<Iterator, fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex>()> edge;
karma::rule<Iterator, std::vector<typename Sys::Cluster::edge_bundle_single>&()> globaledge_range;
karma::rule<Iterator, typename Sys::Cluster::edge_bundle_single()> globaledge;
details::edge_prop_gen<Sys> edge_prop;
details::obj_gen<Sys> objects;
Extractor<Sys> ex;
};
template<typename Sys>
struct vertex_generator : karma::grammar<Iterator, std::vector<typename Sys::Cluster::vertex_bundle>()> {
vertex_generator();
karma::rule<Iterator, std::vector<typename Sys::Cluster::vertex_bundle>()> vertex_range;
karma::rule<Iterator, typename Sys::Cluster::vertex_bundle()> vertex;
details::vertex_prop_gen<Sys> vertex_prop;
details::obj_gen<Sys> objects;
Extractor<Sys> ex;
};
}//details
}//dcm
#ifndef DCM_EXTERNAL_STATE
#include "imp/edge_vertex_generator_imp.hpp"
#endif
#endif

View File

@@ -1,76 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_VERTEX_PARSER_H
#define DCM_EDGE_VERTEX_PARSER_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include <boost/spirit/include/qi.hpp>
#include "opendcm/core/clustergraph.hpp"
#include "extractor.hpp"
#include "object_parser.hpp"
namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
namespace details {
template<typename Sys>
struct edge_parser : qi::grammar< IIterator, fusion::vector<LocalEdge, GlobalEdge, bool, bool>(typename Sys::Cluster*, Sys*),
qi::space_type > {
edge_parser();
details::obj_par<Sys> objects;
Injector<Sys> in;
qi::rule<IIterator, fusion::vector<LocalEdge, GlobalEdge, bool, bool>(typename Sys::Cluster*, Sys*), qi::space_type> edge;
qi::rule<IIterator, typename Sys::Cluster::edge_bundle_single(Sys*), qi::space_type> global_edge;
details::edge_prop_par<Sys> edge_prop;
};
template<typename Sys>
struct vertex_parser : qi::grammar< IIterator, fusion::vector<LocalVertex, GlobalVertex>(typename Sys::Cluster*, Sys*),
qi::space_type> {
vertex_parser();
details::obj_par<Sys> objects;
Injector<Sys> in;
qi::rule<IIterator, fusion::vector<LocalVertex, GlobalVertex>(typename Sys::Cluster*, Sys*), qi::space_type> vertex;
details::vertex_prop_par<Sys> prop;
};
}
}
#ifndef DCM_EXTERNAL_STATE
#include "imp/edge_vertex_parser_imp.hpp"
#endif
#endif

View File

@@ -1,127 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EXTRACTOR_H
#define DCM_EXTRACTOR_H
#include "defines.hpp"
#include <opendcm/core/clustergraph.hpp>
#include <boost/fusion/include/at_c.hpp>
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
template<typename Sys>
struct Extractor {
typedef typename boost::graph_traits<typename Sys::Cluster>::vertex_iterator viter;
typedef typename boost::graph_traits<typename Sys::Cluster>::edge_iterator eiter;
void getVertexRange(typename Sys::Cluster& cluster, std::vector<typename Sys::Cluster::vertex_bundle>& range) {
std::pair<viter, viter> res = boost::vertices(cluster);
for(; res.first != res.second; res.first++)
range.push_back(cluster[*res.first]);
};
void getEdgeRange(typename Sys::Cluster& cluster,
std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >& range) {
std::pair<eiter, eiter> res = boost::edges(cluster);
for(; res.first != res.second; res.first++)
range.push_back(fusion::make_vector(cluster[*res.first],
cluster.getGlobalVertex(boost::source(*res.first, cluster)),
cluster.getGlobalVertex(boost::target(*res.first, cluster))));
};
void getGlobalEdgeSource(typename Sys::Cluster::edge_bundle_single b, int& source) {
source = fusion::at_c<1>(b).source;
};
void getGlobalEdgeTarget(typename Sys::Cluster::edge_bundle_single b, int& target) {
target = fusion::at_c<1>(b).target;
};
void getGlobalEdgeID(typename Sys::Cluster::edge_bundle_single b, int& id) {
id = fusion::at_c<1>(b).ID;
};
void setVertexID(typename Sys::Cluster* cluster, LocalVertex v, long& l) {
if(v)
l = cluster->getGlobalVertex(v);
else
l = 0;
};
void getClusterRange(typename Sys::Cluster& cluster, std::vector<std::pair<GlobalVertex, std::shared_ptr<typename Sys::Cluster> > >& range) {
typedef typename Sys::Cluster::const_cluster_iterator iter;
for(iter it = cluster.m_clusters.begin(); it != cluster.m_clusters.end(); it++) {
range.push_back(std::make_pair(cluster.getGlobalVertex((*it).first), (*it).second));
};
};
};
template<typename Sys>
struct Injector {
void setClusterProperties(typename Sys::Cluster* cluster,
typename details::pts<typename Sys::Cluster::cluster_properties>::type& prop) {
cluster->m_properties = prop;
};
void setVertexProperties(typename Sys::Cluster* cluster, LocalVertex v,
typename details::pts<typename Sys::vertex_properties>::type& prop) {
fusion::at_c<1>(cluster->operator[](v)) = prop;
};
void setVertexObjects(typename Sys::Cluster* cluster, LocalVertex v,
typename details::sps<typename Sys::objects>::type& obj) {
fusion::at_c<2>(cluster->operator[](v)) = obj;
};
void setEdgeProperties(typename Sys::Cluster* cluster, LocalEdge e,
typename details::pts<typename Sys::edge_properties>::type& prop) {
fusion::at_c<0>(cluster->operator[](e)) = prop;
};
void setEdgeBundles(typename Sys::Cluster* cluster, LocalEdge e,
std::vector<typename Sys::Cluster::edge_bundle_single>& bundles) {
fusion::at_c<1>(cluster->operator[](e)) = bundles;
};
void setVertexProperty(typename Sys::Cluster* cluster, int value) {
cluster->template setProperty<details::cluster_vertex_prop>(value);
};
void addClusters(std::vector<std::shared_ptr<typename Sys::Cluster> >& clusters, typename Sys::Cluster* cluster) {
//vertices for the cluster need to be added already (as edges need vertices created)
//so we don't create a vertex here.
typename std::vector<std::shared_ptr<typename Sys::Cluster> >::iterator it;
for(it = clusters.begin(); it != clusters.end(); it++) {
LocalVertex v = cluster->getLocalVertex((*it)->template getProperty<details::cluster_vertex_prop>()).first;
cluster->m_clusters[v] = *it;
};
};
};
}//namespace dcm
#endif //DCM_GENERATOR_H

View File

@@ -1,90 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GENERATOR_H
#define DCM_GENERATOR_H
#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif
#include "property_generator.hpp"
#include "edge_vertex_generator.hpp"
#include "extractor.hpp"
#include <opendcm/core/clustergraph.hpp>
#include "traits.hpp"
#include "imp/traits_impl.hpp"
#include "indent.hpp"
#include <boost/mpl/int.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/fusion/container/vector/convert.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
template<typename Sys>
struct generator : karma::grammar<Iterator, Sys&()> {
typedef typename Sys::Cluster graph;
typedef typename graph::Properties graph_bundle;
typedef typename boost::graph_traits<graph>::vertex_iterator viter;
typedef typename boost::graph_traits<graph>::edge_iterator eiter;
generator();
karma::rule<Iterator, Sys& ()> start;
karma::rule<Iterator, std::pair<GlobalVertex, std::shared_ptr<graph> >()> cluster_pair;
karma::rule<Iterator, graph&()> cluster;
karma::rule<Iterator, Sys&()> system;
details::cluster_prop_gen<Sys> cluster_prop;
details::system_prop_gen<Sys> system_prop;
details::kernel_prop_gen<Sys> kernel_prop;
details::vertex_generator<Sys> vertex_range;
details::edge_generator<Sys> edge_range;
Extractor<Sys> ex;
};
}//namespace dcm
#ifndef DCM_EXTERNAL_STATE
#include "imp/generator_imp.hpp"
#endif
#endif //DCM_GENERATOR_H

View File

@@ -1,58 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_GENERATOR_IMP_H
#define DCM_EDGE_GENERATOR_IMP_H
#include "../edge_vertex_generator.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
template<typename Sys>
edge_generator<Sys>::edge_generator() : edge_generator<Sys>::base_type(edge_range) {
globaledge = karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeID, &ex, karma::_val, karma::_1)]
<< " source=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeSource, &ex, karma::_val, karma::_1)]
<< " target=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeTarget, &ex, karma::_val, karma::_1)] << '>'
<< "#" << objects[karma::_1 = phx::at_c<0>(karma::_val)] << "$\n" ;
globaledge_range = *(karma::lit("<GlobalEdge id=")<<globaledge<<karma::lit("</GlobalEdge>"));
edge = karma::lit("source=")<<karma::int_[karma::_1 = phx::at_c<1>(karma::_val)] << " target="<<karma::int_[karma::_1 = phx::at_c<2>(karma::_val)] << ">#"
<< edge_prop[karma::_1 = phx::at_c<0>(phx::at_c<0>(karma::_val))]
<< karma::eol << globaledge_range[karma::_1 = phx::at_c<1>(phx::at_c<0>(karma::_val))] << '$' << karma::eol;
edge_range = (karma::lit("<Edge ") << edge << karma::lit("</Edge>")) % karma::eol;
};
template<typename Sys>
vertex_generator<Sys>::vertex_generator() : vertex_generator<Sys>::base_type(vertex_range) {
vertex = karma::int_ << ">#" << vertex_prop << objects << "$\n";
vertex_range = '\n' << (karma::lit("<Vertex id=") << vertex << karma::lit("</Vertex>")) % karma::eol;
};
}//details
}//dcm
#endif

View File

@@ -1,55 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_PARSER_IMP_H
#define DCM_EDGE_PARSER_IMP_H
#include "../edge_vertex_parser.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
template<typename Sys>
edge_parser<Sys>::edge_parser() : edge_parser<Sys>::base_type(edge) {
global_edge = qi::lit("<GlobalEdge") >> qi::lit("id=") >> qi::int_[phx::bind(&GlobalEdge::ID, phx::at_c<1>(qi::_val)) = qi::_1]
>> qi::lit("source=") >> qi::int_[phx::bind(&GlobalEdge::source, phx::at_c<1>(qi::_val)) = qi::_1]
>> qi::lit("target=") >> qi::int_[phx::bind(&GlobalEdge::target, phx::at_c<1>(qi::_val)) = qi::_1] >> '>'
>> objects(qi::_r1)[phx::at_c<0>(qi::_val) = qi::_1] >> "</GlobalEdge>";
edge = (qi::lit("<Edge") >> "source=" >> qi::int_ >> "target=" >> qi::int_ >> '>')[qi::_val = phx::bind((&Sys::Cluster::addEdgeGlobal), qi::_r1, qi::_1, qi::_2)]
>> edge_prop[phx::bind(&Injector<Sys>::setEdgeProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> (*global_edge(qi::_r2))[phx::bind(&Injector<Sys>::setEdgeBundles, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> ("</Edge>");
};
template<typename Sys>
vertex_parser<Sys>::vertex_parser() : vertex_parser<Sys>::base_type(vertex) {
vertex = qi::lit("<Vertex id=") >> qi::int_[qi::_val = phx::bind(&Sys::Cluster::addVertex, qi::_r1, qi::_1)]
>> '>' >> prop[phx::bind(&Injector<Sys>::setVertexProperties, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> objects(qi::_r2)[phx::bind(&Injector<Sys>::setVertexObjects, &in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> ("</Vertex>");
};
}//details
}//dcm
#endif

View File

@@ -1,73 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GENERATOR_IMP_H
#define DCM_GENERATOR_IMP_H
#include "../generator.hpp"
#include "opendcm/core/clustergraph.hpp"
#include "../defines.hpp"
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/struct.hpp>
namespace boost {
namespace spirit {
namespace traits
{
template <typename T1, typename T2, typename T3, typename T4>
struct transform_attribute<std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> > const, dcm::ClusterGraph<T1,T2,T3,T4>&, karma::domain>
{
typedef dcm::ClusterGraph<T1,T2,T3,T4>& type;
static type pre(std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> > const& val) {
return *val;
}
};
}
}
}
namespace dcm {
template<typename Sys>
generator<Sys>::generator() : generator<Sys>::base_type(start) {
cluster %= karma::omit[karma::int_] << cluster_prop
<< -karma::buffer[karma::eol << (cluster_pair % karma::eol)[phx::bind(&Extractor<Sys>::getClusterRange, &ex, karma::_val, karma::_1)]]
<< -vertex_range[phx::bind(&Extractor<Sys>::getVertexRange, &ex, karma::_val, karma::_1)]
<< -karma::buffer[karma::eol << edge_range[phx::bind(&Extractor<Sys>::getEdgeRange, &ex, karma::_val, karma::_1)]]
<< "$" << karma::eol
<< karma::lit("</Cluster>");
cluster_pair %= karma::lit("<Cluster id=") << karma::int_ << ">#"
<< qi::attr_cast<std::shared_ptr<graph>, graph&>(cluster);
system %= system_prop << karma::lit("<Kernel>#") << kernel_prop
<< "$" << karma::eol << karma::lit("</Kernel>") << karma::eol
<< karma::lit("<Cluster id=0>#") << qi::attr_cast<std::shared_ptr<graph>, graph&>(cluster);
start %= karma::lit("<openDCM>#") << karma::eol << system << "$" << karma::eol << karma::lit("</openDCM>");
};
}//namespace dcm
#endif //DCM_GENERATOR_H

View File

@@ -1,70 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE_STATE_IMP_H
#define DCM_MODULE_STATE_IMP_H
#include <iosfwd>
#include "../module.hpp"
#include "../indent.hpp"
#include "../generator.hpp"
#include "../parser.hpp"
#include "../defines.hpp"
namespace qi = boost::spirit::qi;
namespace dcm {
template<typename Sys>
void ModuleState::type<Sys>::inheriter::saveState(std::ostream& stream) {
boost::iostreams::filtering_ostream indent_stream;
indent_stream.push(indent_filter());
indent_stream.push(stream);
std::ostream_iterator<char> out(indent_stream);
generator<Sys> gen;
karma::generate(out, gen, *m_this);
};
template<typename Sys>
void ModuleState::type<Sys>::inheriter::loadState(std::istream& stream) {
//disable skipping of whitespace
stream.unsetf(std::ios::skipws);
// wrap istream into iterator
boost::spirit::istream_iterator begin(stream);
boost::spirit::istream_iterator end;
// use iterator to parse file data
parser<Sys> par;
m_this->clear();
qi::phrase_parse(begin, end, par, qi::space, *m_this);
};
}
#endif //DCM_MODULE_STATE_H

View File

@@ -1,58 +0,0 @@
#ifndef DCM_OBJECT_GENERATOR_IMP_H
#define DCM_OBJECT_GENERATOR_IMP_H
#include "traits_impl.hpp"
#include "../object_generator.hpp"
#include "property_generator_imp.hpp"
#include "boost/phoenix/fusion/at.hpp"
#include <boost/phoenix/bind.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
namespace details {
template<typename Sys, typename Object, typename Gen>
obj_grammar<Sys, Object,Gen>::obj_grammar() : obj_grammar<Sys, Object,Gen>::base_type(start) {
Gen::init(subrule);
start = karma::lit("\n<Object>") << '#' << karma::eol << subrule
<< prop[phx::bind(&obj_grammar::getProperties, karma::_val, karma::_1)]
<< '$' << karma::eol << karma::lit("</Object>");
};
template<typename Sys, typename Object, typename Gen>
void obj_grammar<Sys, Object,Gen>::getProperties(std::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq) {
if(ptr) seq = ptr->m_properties;
else {
//TODO: throw
};
};
template<typename Sys>
obj_gen<Sys>::obj_gen() : obj_gen<Sys>::base_type(obj) {
obj = -(karma::eps(valid<0>::value) << karma::eps(phx::at_c<index<0>::value>(karma::_val)) << fusion::at<index<0> >(rules)[karma::_1 = phx::at_c<index<0>::value>(karma::_val)])
<< -(karma::eps(valid<1>::value) << karma::eps(phx::at_c<index<1>::value>(karma::_val)) << fusion::at<index<1> >(rules)[karma::_1 = phx::at_c<index<1>::value>(karma::_val)])
<< -(karma::eps(valid<2>::value) << karma::eps(phx::at_c<index<2>::value>(karma::_val)) << fusion::at<index<2> >(rules)[karma::_1 = phx::at_c<index<2>::value>(karma::_val)])
<< -(karma::eps(valid<3>::value) << karma::eps(phx::at_c<index<3>::value>(karma::_val)) << fusion::at<index<3> >(rules)[karma::_1 = phx::at_c<index<3>::value>(karma::_val)])
<< -(karma::eps(valid<4>::value) << karma::eps(phx::at_c<index<4>::value>(karma::_val)) << fusion::at<index<4> >(rules)[karma::_1 = phx::at_c<index<4>::value>(karma::_val)])
<< -(karma::eps(valid<5>::value) << karma::eps(phx::at_c<index<5>::value>(karma::_val)) << fusion::at<index<5> >(rules)[karma::_1 = phx::at_c<index<5>::value>(karma::_val)])
<< -(karma::eps(valid<6>::value) << karma::eps(phx::at_c<index<6>::value>(karma::_val)) << fusion::at<index<6> >(rules)[karma::_1 = phx::at_c<index<6>::value>(karma::_val)])
<< -(karma::eps(valid<7>::value) << karma::eps(phx::at_c<index<7>::value>(karma::_val)) << fusion::at<index<7> >(rules)[karma::_1 = phx::at_c<index<7>::value>(karma::_val)])
<< -(karma::eps(valid<8>::value) << karma::eps(phx::at_c<index<8>::value>(karma::_val)) << fusion::at<index<8> >(rules)[karma::_1 = phx::at_c<index<8>::value>(karma::_val)])
<< -(karma::eps(valid<9>::value) << karma::eps(phx::at_c<index<9>::value>(karma::_val)) << fusion::at<index<9> >(rules)[karma::_1 = phx::at_c<index<9>::value>(karma::_val)]);
};
} //namespace details
}//dcm
#endif //DCM_OBJECT_GENERATOR_H

View File

@@ -1,88 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_OBJECT_PARSER_IMP_H
#define DCM_OBJECT_PARSER_IMP_H
#include "../object_parser.hpp"
#include "property_parser_imp.hpp"
#include "boost/phoenix/fusion/at.hpp"
namespace dcm {
namespace details {
template<typename srs, typename prs, typename dist>
typename boost::enable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_obj_init(srs& sseq, prs& pseq) {
if(dist::value == 0) {
fusion::at<dist>(pseq) %= fusion::at<dist>(sseq)(qi::_r1, qi::_r2);
}
else {
fusion::at<dist>(pseq) %= fusion::at<typename mpl::prior< typename mpl::max<dist, mpl::int_<1> >::type >::type>(pseq)(qi::_r1, qi::_r2) | fusion::at<dist>(sseq)(qi::_r1, qi::_r2);
}
recursive_obj_init<srs, prs, typename mpl::next<dist>::type>(sseq, pseq);
};
template<typename srs, typename prs, typename dist>
typename boost::disable_if<mpl::less< dist, mpl::size<srs> >, void >::type recursive_obj_init(srs& sseq, prs& pseq) {};
template<typename Sys, typename ObjList, typename Object, typename Par>
obj_parser<Sys, ObjList, Object, Par>::obj_parser(): obj_parser::base_type(start) {
typedef typename mpl::find<ObjList, Object>::type::pos pos;
Par::init(subrule);
start = qi::lit("<Object>") >> subrule(qi::_r2)[phx::at_c<pos::value>(*qi::_r1) = qi::_1]
>> qi::eps(phx::at_c<pos::value>(*qi::_r1))[ phx::bind(&Sys::template push_back<Object>, qi::_r2, phx::at_c<pos::value>(*qi::_r1))]
>> prop[phx::bind(&obj_parser::setProperties, phx::at_c<pos::value>(*qi::_r1), qi::_1)]
>> qi::lit("</Object>");
};
template<typename Sys, typename ObjList, typename Object, typename Par>
void obj_parser<Sys, ObjList, Object, Par>::setProperties(std::shared_ptr<Object> ptr, typename details::pts<typename Object::PropertySequence>::type& seq) {
if(ptr) ptr->m_properties = seq;
};
template<typename ParentRuleSequence, typename Rule>
typename boost::disable_if<typename fusion::result_of::empty<ParentRuleSequence>::type, void>::type
initalizeLastObjRule(ParentRuleSequence& pr, Rule& r) {
r = *(fusion::back(pr)(&qi::_val, qi::_r1));
};
template<typename ParentRuleSequence, typename Rule>
typename boost::enable_if<typename fusion::result_of::empty<ParentRuleSequence>::type, void>::type
initalizeLastObjRule(ParentRuleSequence& pr, Rule& r) {};
template<typename Sys>
obj_par<Sys>::obj_par(): obj_par<Sys>::base_type(obj) {
recursive_obj_init<typename fusion::result_of::as_vector<sub_rules_sequence>::type,
typename fusion::result_of::as_vector<parent_rules_sequence>::type,
mpl::int_<0> >(sub_rules, parent_rules);
initalizeLastObjRule(parent_rules, obj);
};
}//details
}//DCM
#endif

View File

@@ -1,77 +0,0 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PARSER_IMP_H
#define DCM_PARSER_IMP_H
#include <boost/spirit/include/qi_attr_cast.hpp>
#include "opendcm/core/system.hpp"
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include "../parser.hpp"
#include "../defines.hpp"
namespace boost {
namespace spirit {
namespace traits
{
template <typename T1, typename T2, typename T3, typename T4>
struct transform_attribute<std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> >, typename dcm::ClusterGraph<T1,T2,T3,T4>::Properties, qi::domain>
{
typedef typename dcm::ClusterGraph<T1,T2,T3,T4>::Properties& type;
static type pre(std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> >& val) {
return val->m_properties;
}
static void post(std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> >const& val, typename dcm::ClusterGraph<T1,T2,T3,T4>::Properties const& attr) {}
static void fail(std::shared_ptr<dcm::ClusterGraph<T1,T2,T3,T4> > const&) {}
};
}
}
}
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
template<typename Sys>
parser<Sys>::parser() : parser<Sys>::base_type(system) {
cluster %= qi::lit("<Cluster id=") >> qi::omit[qi::int_[qi::_a = qi::_1]] >> ">"
>> -(qi::eps(qi::_a > 0)[qi::_val = phx::construct<std::shared_ptr<graph> >(phx::new_<typename Sys::Cluster>())])
>> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, &(*qi::_val), true)]
>> qi::eps[phx::bind(&Injector<Sys>::setVertexProperty, &in, &(*qi::_val), qi::_a)]
>> qi::attr_cast<std::shared_ptr<graph>, typename graph::Properties>(cluster_prop >> qi::eps)
>> qi::omit[(*cluster(qi::_r1))[qi::_b = qi::_1]]
>> qi::omit[*vertex(&(*qi::_val), qi::_r1)]
>> qi::omit[*edge(&(*qi::_val), qi::_r1)]
>> qi::eps[phx::bind(&Injector<Sys>::addClusters, &in, qi::_b, &(*qi::_val))]
>> qi::eps[phx::bind(&Sys::Cluster::setCopyMode, &(*qi::_val), false)]
>> "</Cluster>";
system %= qi::lit("<openDCM>") >> -system_prop
>> qi::lit("<Kernel>") >> -kernel_prop >> qi::lit("</Kernel>")
>> cluster(&qi::_val) >> qi::lit("</openDCM>");
};
}
#endif //DCM_PARSER_H

Some files were not shown because too many files have changed in this diff Show More