[Assembly] remove it
as discussed: https://forum.freecadweb.org/viewtopic.php?p=582152#p582152
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -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"
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -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})
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,3 +0,0 @@
|
||||
/usr/include/eigen3
|
||||
/home/stefan/Projects/openDCM/opendcm/
|
||||
/home/stefan/Projects/openDCM/
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user