Révision 1

MyDefaultContactManager.h (revision 1)
1
/******************************************************************************
2
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
3
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
4
*                                                                             *
5
* This library is free software; you can redistribute it and/or modify it     *
6
* under the terms of the GNU Lesser General Public License as published by    *
7
* the Free Software Foundation; either version 2.1 of the License, or (at     *
8
* your option) any later version.                                             *
9
*                                                                             *
10
* This library is distributed in the hope that it will be useful, but WITHOUT *
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13
* for more details.                                                           *
14
*                                                                             *
15
* You should have received a copy of the GNU Lesser General Public License    *
16
* along with this library; if not, write to the Free Software Foundation,     *
17
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
18
*******************************************************************************
19
*                               SOFA :: Modules                               *
20
*                                                                             *
21
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
22
*                                                                             *
23
* Contact information: contact@sofa-framework.org                             *
24
******************************************************************************/
25
#ifndef SOFA_COMPONENT_COLLISION_MYDEFAULTCONTACTMANAGER_H
26
#define SOFA_COMPONENT_COLLISION_MYDEFAULTCONTACTMANAGER_H
27

  
28
#include <sofa/core/collision/ContactManager.h>
29
#include <sofa/simulation/common/Node.h>
30
#include <sofa/component/component.h>
31
#include <sofa/helper/OptionsGroup.h>
32
#include <sofa/helper/map_ptr_stable_compare.h>
33
#include <vector>
34

  
35
#include "initAFM_plane.h"
36

  
37
namespace sofa
38
{
39

  
40
namespace component
41
{
42

  
43
namespace collision
44
{
45

  
46
class SOFA_AFM_plane_API MyDefaultContactManager : public core::collision::ContactManager
47
{
48
public :
49
    SOFA_CLASS(MyDefaultContactManager,sofa::core::collision::ContactManager);
50

  
51
protected:
52
    typedef sofa::helper::map_ptr_stable_compare<std::pair<core::CollisionModel*,core::CollisionModel*>,core::collision::Contact::SPtr> ContactMap;
53
    ContactMap contactMap;
54
    //typedef struct MaProfondeur{bool aTouche; double origine[3];} Profondeur;
55

  
56
    void cleanup();
57
public:
58
    //typedef struct MaProfondeur{bool aTouche; double origine[3];} Profondeur;
59

  
60
    Data<double> deepInMeristem;
61
    Data<bool> aTouche;
62
    Data<sofa::helper::vector<double> > origine;
63
    Data<sofa::helper::OptionsGroup> response;
64
    Data<std::string> responseParams;
65
protected:
66
    MyDefaultContactManager();
67
    ~MyDefaultContactManager();
68
    void setContactTags(core::CollisionModel* model1, core::CollisionModel* model2, core::collision::Contact::SPtr contact);
69

  
70
    //double deepInMeristem;
71
    //Profondeur penetration;
72

  
73
public:
74

  
75
//	bool CollisionDetected(){return penetration.aTouche;}
76
//	double getDepth(){return deepInMeristem;}
77
    bool CollisionDetected(){return aTouche.getValue();}
78
    double getDepth(){return deepInMeristem.getValue();}
79
    /// outputsVec fixes the reproducibility problems by storing contacts in the collision detection saved order
80
    /// if not given, it is still working but with eventual reproducibility problems
81
    void createContacts(const DetectionOutputMap& outputs);
82

  
83
    void init();
84
    void draw(const core::visual::VisualParams* vparams);
85

  
86
    template<class T>
87
    static typename T::SPtr create(T*, core::objectmodel::BaseContext* context, core::objectmodel::BaseObjectDescription* arg)
88
    {
89
        typename T::SPtr obj = sofa::core::objectmodel::New<T>();
90

  
91
        if (context)
92
        {
93
            context->addObject(obj);
94
            core::collision::Pipeline *pipeline = static_cast<simulation::Node*>(context)->collisionPipeline;
95
            sofa::helper::OptionsGroup options = initializeResponseOptions(pipeline);
96
            obj->response.setValue(options);
97
        }
98

  
99
        if (arg)
100
            obj->parse(arg);
101

  
102
        return obj;
103
    }
104

  
105
    virtual std::string getContactResponse(core::CollisionModel* model1, core::CollisionModel* model2);
106

  
107
    /// virtual methods used for cleaning the pipeline after a dynamic graph node deletion.
108
    /**
109
     * Contacts can be attached to a deleted node and their deletion is a problem for the pipeline.
110
     * @param c is the list of deleted contacts.
111
     */
112
    virtual void removeContacts(const ContactVector &/*c*/);
113
    void setDefaultResponseType(const std::string &responseT)
114
    {
115
        if (response.getValue().size() == 0)
116
        {
117
            helper::vector<std::string> listResponse(1,responseT);
118

  
119
            sofa::helper::OptionsGroup responseOptions(listResponse);
120
            response.setValue(responseOptions);
121
        }
122
        else
123
        {
124
            sofa::helper::OptionsGroup* options = response.beginEdit();
125

  
126
            options->setSelectedItem(responseT);
127
            response.endEdit();
128
        }
129
    }
130

  
131
    std::string getDefaultResponseType() const { return response.getValue().getSelectedItem(); }
132

  
133
protected:
134
    static sofa::helper::OptionsGroup initializeResponseOptions(core::collision::Pipeline *pipeline);
135

  
136
    std::map<Instance,ContactMap> storedContactMap;
137

  
138
    virtual void changeInstance(Instance inst)
139
    {
140
        core::collision::ContactManager::changeInstance(inst);
141
        storedContactMap[instance].swap(contactMap);
142
        contactMap.swap(storedContactMap[inst]);
143
    }
144

  
145
    // count failure messages, so we don't continuously repeat them
146
    std::map<std::pair<std::string,std::pair<std::string,std::string> >, int> errorMsgCount;
147
};
148

  
149
} // namespace collision
150

  
151
} // namespace component
152

  
153
} // namespace sofa
154

  
155
#endif
initAFM_plane.cpp (revision 1)
1
 
2
/******************************************************************************
3
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
4
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
5
*                                                                             *
6
* This library is free software; you can redistribute it and/or modify it     *
7
* under the terms of the GNU Lesser General Public License as published by    *
8
* the Free Software Foundation; either version 2.1 of the License, or (at     *
9
* your option) any later version.                                             *
10
*                                                                             *
11
* This library is distributed in the hope that it will be useful, but WITHOUT *
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
14
* for more details.                                                           *
15
*                                                                             *
16
* You should have received a copy of the GNU Lesser General Public License    *
17
* along with this library; if not, write to the Free Software Foundation,     *
18
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
19
*******************************************************************************
20
*                               SOFA :: Plugins                               *
21
*                                                                             *
22
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
23
*                                                                             *
24
* Contact information: contact@sofa-framework.org                             *
25
******************************************************************************/
26
#include "initAFM_plane.h"
27

  
28
namespace sofa
29
{
30

  
31
namespace component
32
{
33

  
34
	//Here are just several convenient functions to help user to know what contains the plugin
35

  
36
	extern "C" {
37
                SOFA_AFM_plane_API void initExternalModule();
38
                SOFA_AFM_plane_API const char* getModuleName();
39
                SOFA_AFM_plane_API const char* getModuleVersion();
40
                SOFA_AFM_plane_API const char* getModuleLicense();
41
                SOFA_AFM_plane_API const char* getModuleDescription();
42
                SOFA_AFM_plane_API const char* getModuleComponentList();
43
	}
44
	
45
	void initExternalModule()
46
	{
47
		static bool first = true;
48
		if (first)
49
		{
50
			first = false;
51
		}
52
	}
53

  
54
	const char* getModuleName()
55
	{
56
	  return "AFM_plane";
57
	}
58

  
59
	const char* getModuleVersion()
60
	{
61
		return "0.2";
62
	}
63

  
64
	const char* getModuleLicense()
65
	{
66
		return "LGPL";
67
	}
68

  
69

  
70
	const char* getModuleDescription()
71
	{
72
		return "TODO: replace this with the description of your plugin";
73
	}
74

  
75
	const char* getModuleComponentList()
76
	{
77
	  /// string containing the names of the classes provided by the plugin
78
	  return "";
79
	  //return "MyMappingPendulumInPlane, MyBehaviorModel, MyProjectiveConstraintSet";
80
	}
81

  
82

  
83

  
84
} 
85

  
86
} 
87

  
88
/// Use the SOFA_LINK_CLASS macro for each class, to enable linking on all platforms
89
SOFA_LINK_CLASS(MyDefaultContactManager)
README.txt (revision 1)
1
Author : R. Malgat, F. Faure, A. Boudaoud.
2

  
3
This plugin works with the Software Open Framework Architecture (SOFA).
4
It is a simulated Atomic Force Microscope acting on a plane.
5

  
6
To get an idea of the scene, you can launch Sofa on the example examples/plane.py. The scene appearing should be like the image plane.png and gives you an overview of the scene described.
7
Then to use the AFM and trace curves, simply install the folder as a SOFA plugin. Go to the examples folder and launch the application called AFM which should be under "YourPathToSofa/build_release/bin/AFM". You should get a resulting curve called AFM-results.txt, where, for each line, the force and the corresponding depth is written.
8
Feel free to change the parameters : pressure, elastic modulus, poisson ratio... 
9

  
10
If Sofa does not find the path to the plugin when you launch the AFM application, you may have to change the paths in the file AFM/AFM.cpp line 112 and eventually line 129. 
initAFM_plane.h (revision 1)
1
 
2
/******************************************************************************
3
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
4
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
5
*                                                                             *
6
* This library is free software; you can redistribute it and/or modify it     *
7
* under the terms of the GNU Lesser General Public License as published by    *
8
* the Free Software Foundation; either version 2.1 of the License, or (at     *
9
* your option) any later version.                                             *
10
*                                                                             *
11
* This library is distributed in the hope that it will be useful, but WITHOUT *
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
14
* for more details.                                                           *
15
*                                                                             *
16
* You should have received a copy of the GNU Lesser General Public License    *
17
* along with this library; if not, write to the Free Software Foundation,     *
18
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
19
*******************************************************************************
20
*                               SOFA :: Plugins                               *
21
*                                                                             *
22
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
23
*                                                                             *
24
* Contact information: contact@sofa-framework.org                             *
25
******************************************************************************/
26
#ifndef INITAFM_plane_H
27
#define INITAFM_plane_H
28

  
29

  
30
#include <sofa/helper/system/config.h>
31

  
32
#ifdef SOFA_BUILD_AFM_plane
33
#define SOFA_AFM_plane_API SOFA_EXPORT_DYNAMIC_LIBRARY
34
#else
35
#define SOFA_AFM_plane_API  SOFA_IMPORT_DYNAMIC_LIBRARY
36
#endif
37

  
38

  
39
#endif // INITAFM_plane_H
CMakeLists.txt (revision 1)
1
include(${SOFA_CMAKE_DIR}/preProject.cmake)
2

  
3
##plugin external dependencies
4
#find_package( REQUIRED)
5
#include_directories(${})
6

  
7
set(HEADER_FILES
8

  
9
initAFM_plane.h
10
MyDefaultContactManager.h
11
	)
12

  
13
set(SOURCE_FILES
14

  
15
initAFM_plane.cpp
16
MyDefaultContactManager.cpp
17
	)
18

  
19
set(README_FILES
20

  
21
	
22
	)
23
	
24

  
25
add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${MOC_FILES} ${SOURCE_FILES} ${README_FILES})
26

  
27
AddCompilerDefinitions("SOFA_BUILD_AFM-plane")
28
AddLinkerDependencies(SofaGuiQt)
29

  
30
include(${SOFA_CMAKE_DIR}/postProject.cmake)
examples/AFM-results.txt (revision 1)
1
### first the force then the depth ###
2

  
3
0.1 0.0566023
4
0.2 0.0629732
5
0.3 0.0707535
6
0.4 0.0788602
7
0.5 0.0870693
8
0.6 0.0951414
9
0.7 0.103042
10
0.8 0.110816
11
0.9 0.118506
12
1 0.126105
13
1.1 0.13365
14
1.2 0.141175
15
1.3 0.148656
16
1.4 0.156105
examples/plane.py (revision 1)
1
import Sofa
2

  
3
poissonRatio = 0.49
4
youngModulus = 100
5
pressure = 5
6

  
7
indentorRadius = 0.3
8

  
9
def createScene(node): 
10
    
11
    print 'Creation of Sofa SceneGraph'    
12
    
13
    node.gravity = [0,0,0]
14

  
15
    node.createObject('RequiredPlugin', pluginName="Flexible") 
16
    
17
    node.createObject('VisualStyle', displayFlags = 'showVisual hideBehavior showCollisionModels')
18
    node.createObject('DefaultPipeline', name="DefaultCollisionPipeline",  verbose="0",  draw="0",  depth="6")
19
    node.createObject('BruteForceDetection', name="Detection")
20
    node.createObject('MinProximityIntersection', name="Proximity",  alarmDistance="0.1",  contactDistance="0.0")
21
    node.createObject('DefaultContactManager', name="Response",  response="default", responseParams="")
22
    node.createObject('TreeCollisionGroupManager', name="Group")
23

  
24
    node.createObject('CGLinearSolver', template="GraphScattered",iterations=500,threshold=1e-10,tolerance=1e-10)
25
    node.createObject('EulerImplicitSolver', rayleighStiffness=0.5,rayleighMass=0.5)
26

  
27
    node.createObject('GridMeshCreator', name='Grid', resolution="10 10", triangulate=1)
28
    node.createObject('MeshTopology', name='Topology',src="@Grid")
29
    node.createObject('MechanicalObject', name='DOFs', template="Vec3d")    
30
    node.createObject('UniformMass',name='mass', template='Vec3d')
31
    node.createObject('FixedConstraint',template="Vec3d", indices="0 9 90 99" )
32

  
33
    ## Pressure
34
    node.createObject("SurfacePressureForceField",  pressure=pressure)
35

  
36
    ## Deformation, Stress and Strain
37
    node.createObject('BarycentricShapeFunction', template="ShapeFunctiond")
38
    deformation = node.createChild("deformation")
39
    deformation.createObject('TopologyGaussPointSampler',name='sampler', inPosition='@../Topology.position' , showSamples="false", method="0", order="1" )
40
    deformation.createObject('MechanicalObject', name='deform', template='F321')
41
    deformation.createObject('LinearMapping', template='Vec3d,F321')
42
    stressStrain = deformation.createChild('stressStrain')
43
    stressStrain.createObject('MechanicalObject', name='Strain',template='E321')
44
    stressStrain.createObject('CorotationalStrainMapping', template="F321,E321")
45
    stressStrain.createObject('HookeForceField', template="E321", youngModulus=youngModulus,poissonRatio=poissonRatio, viscosity=0  )
46

  
47
    ## Collision
48
    node.createObject('TriangleModel',contactStiffness=1000)
49
    node.createObject('LineModel',contactStiffness=1000)
50
    node.createObject('PointModel',contactStiffness=1000)
51
    Visu = node.createChild('Visu')
52
    Visu.createObject('OglModel')
53
    Visu.createObject('IdentityMapping', template='Vec3d,ExtVec3f')
54

  
55
    ## indentor
56
    indentor = node.createChild('indentor')
57
    indentor.createObject('MechanicalObject',name='indentor', position="0.5 0.5 2")
58
    indentor.createObject('UniformMass')
59
    indentor.createObject('ConstantForceField', points=0, force="0 0 -1")
60
    indentor.createObject('TSphereModel', radius= indentorRadius, ContactStiffness=1000) 
61
    indentor.createObject('ProjectToLineConstraint',endTime='-1', indices=0, origin="0.5 0.5 2", direction="0 0 1") 
62
    indentor.createObject('PointConstraint', endTime=3, indices=0)                     
examples/AFM-plane.py (revision 1)
1
import Sofa
2

  
3
poissonRatio = 0.49
4
youngModulus = 100
5
pressure = 5
6

  
7
indentorRadius = 0.3
8

  
9
def createScene(node): 
10
    
11
    print 'Creation of Sofa SceneGraph'    
12
    
13
    node.gravity = [0,0,0]
14

  
15
    node.createObject('RequiredPlugin', pluginName="Flexible") 
16
    node.createObject('RequiredPlugin', pluginName="AFM_plane")
17

  
18
    node.createObject('VisualStyle', displayFlags = 'showVisual hideBehavior showCollisionModels')
19
    node.createObject('DefaultPipeline', name="DefaultCollisionPipeline",  verbose="0",  draw="0",  depth="6")
20
    node.createObject('BruteForceDetection', name="Detection")
21
    node.createObject('MinProximityIntersection', name="Proximity",  alarmDistance="0.05",  contactDistance="0.0")
22
    node.createObject('MyDefaultContactManager', name="Response",  response="default", responseParams="")
23
    node.createObject('TreeCollisionGroupManager', name="Group")
24

  
25
    node.createObject('CGLinearSolver', template="GraphScattered",iterations=500,threshold=1e-10,tolerance=1e-10)
26
    node.createObject('EulerImplicitSolver', rayleighStiffness=0.5,rayleighMass=0.5)
27

  
28
    node.createObject('GridMeshCreator', name='Grid', resolution="10 10", triangulate=1)
29
    node.createObject('MeshTopology', name='Topology',src="@Grid")
30
    node.createObject('MechanicalObject', name='DOFs', template="Vec3d")    
31
    node.createObject('UniformMass',name='mass', template='Vec3d')
32
    node.createObject('FixedConstraint',template="Vec3d", indices="0 9 90 99" )
33

  
34
    ## Pressure
35
    node.createObject("SurfacePressureForceField",  pressure=pressure)
36

  
37
    ## Deformation, Stress and Strain
38
    node.createObject('BarycentricShapeFunction', template="ShapeFunctiond")
39
    deformation = node.createChild("deformation")
40
    deformation.createObject('TopologyGaussPointSampler',name='sampler', inPosition='@../Topology.position' , showSamples="false", method="0", order="1" )
41
    deformation.createObject('MechanicalObject', name='deform', template='F321')
42
    deformation.createObject('LinearMapping', template='Vec3d,F321')
43
    stressStrain = deformation.createChild('stressStrain')
44
    stressStrain.createObject('MechanicalObject', name='Strain',template='E321')
45
    stressStrain.createObject('CorotationalStrainMapping', template="F321,E321")
46
    stressStrain.createObject('HookeForceField', template="E321", youngModulus=youngModulus,poissonRatio=poissonRatio, viscosity=0  )
47

  
48
    ## Collision
49
    node.createObject('TriangleModel',contactStiffness=1000,group=0)
50
    node.createObject('LineModel',contactStiffness=1000,group=0)
51
    node.createObject('PointModel',contactStiffness=1000,group=0)
52
    Visu = node.createChild('Visu')
53
    Visu.createObject('OglModel')
54
    Visu.createObject('IdentityMapping', template='Vec3d,ExtVec3f')
55

  
56
    ## indentor
57
    indentor = node.createChild('indentor')
58
    indentor.createObject('MechanicalObject',name='indentor', position="0.5 0.5 2")
59
    indentor.createObject('UniformMass')
60
    indentor.createObject('ConstantForceField', points=0, force="0 0 -1")
61
    indentor.createObject('TSphereModel', radius= indentorRadius, ContactStiffness=1000, group=1) 
62
    indentor.createObject('ProjectToLineConstraint',endTime='-1', indices=0, origin="0.5 0.5 2", direction="0 0 1") 
63
    indentor.createObject('PointConstraint', endTime=3, indices=0)                     
MyDefaultContactManager.cpp (revision 1)
1
/******************************************************************************
2
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
3
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
4
*                                                                             *
5
* This library is free software; you can redistribute it and/or modify it     *
6
* under the terms of the GNU Lesser General Public License as published by    *
7
* the Free Software Foundation; either version 2.1 of the License, or (at     *
8
* your option) any later version.                                             *
9
*                                                                             *
10
* This library is distributed in the hope that it will be useful, but WITHOUT *
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13
* for more details.                                                           *
14
*                                                                             *
15
* You should have received a copy of the GNU Lesser General Public License    *
16
* along with this library; if not, write to the Free Software Foundation,     *
17
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
18
*******************************************************************************
19
*                               SOFA :: Modules                               *
20
*                                                                             *
21
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
22
*                                                                             *
23
* Contact information: contact@sofa-framework.org                             *
24
******************************************************************************/
25
//#include <sofa/component/collision/DefaultContactManager.h>
26

  
27
#include "MyDefaultContactManager.h"
28
#include <sofa/core/visual/VisualParams.h>
29
#include <sofa/core/ObjectFactory.h>
30
#include <sofa/core/objectmodel/Tag.h>
31

  
32

  
33
namespace sofa
34
{
35

  
36
namespace component
37
{
38

  
39
namespace collision
40
{
41

  
42
SOFA_DECL_CLASS(MyDefaultContactManager)
43

  
44
int MyDefaultContactManagerClass = core::RegisterObject("My Default class to create reactions to the collisions")
45
        .add< MyDefaultContactManager >()
46
        .addAlias("MyCollisionResponse")
47
        ;
48

  
49
MyDefaultContactManager::MyDefaultContactManager()
50
    : response(initData(&response, "response", "contact response class"))
51
    , responseParams(initData(&responseParams, "responseParams", "contact response parameters (syntax: name1=value1&name2=value2&...)"))
52
    //,deepInMeristem(0.0)
53
    ,deepInMeristem(initData(&deepInMeristem,"deepInMeristem","how deep we are in the meristem"))
54
    ,aTouche(initData(&aTouche,"aTouche","has there been a collision between the meristem and the indentor"))
55
    ,origine(initData(&origine,"origine","origine of collision between the meristem and the indentor"))
56
{
57
}
58

  
59
MyDefaultContactManager::~MyDefaultContactManager()
60
{
61
    // Contacts are now attached to the graph.
62
    // So they will be deleted by the DeleteVisitor
63
    // FIX crash on unload bug. -- J. Allard
64
    //clear();
65
}
66

  
67
sofa::helper::OptionsGroup MyDefaultContactManager::initializeResponseOptions(core::collision::Pipeline *pipeline)
68
{
69
    helper::set<std::string> listResponse;
70
    if (pipeline) listResponse=pipeline->getResponseList();
71
    else
72
    {
73
        core::collision::Contact::Factory::iterator it;
74
        for (it=core::collision::Contact::Factory::getInstance()->begin(); it!=core::collision::Contact::Factory::getInstance()->end(); ++it)
75
        {
76
            listResponse.insert(it->first);
77
        }
78
    }
79
    sofa::helper::OptionsGroup responseOptions(listResponse);
80
    if (listResponse.find("default") != listResponse.end())
81
        responseOptions.setSelectedItem("default");
82
    return responseOptions;
83
}
84

  
85
void MyDefaultContactManager::init()
86
{
87

  
88
    aTouche.setValue(false);
89

  
90
    if (response.getValue().size() == 0)
91
    {
92
        core::collision::Pipeline *pipeline=static_cast<simulation::Node*>(getContext())->collisionPipeline;
93
        response.setValue(initializeResponseOptions(pipeline));
94
    }
95
}
96

  
97
void MyDefaultContactManager::cleanup()
98
{
99
    for (sofa::helper::vector<core::collision::Contact::SPtr>::iterator it=contacts.begin(); it!=contacts.end(); ++it)
100
    {
101
        (*it)->removeResponse();
102
        (*it)->cleanup();
103
        //delete *it;
104
        it->reset();
105
    }
106
    contacts.clear();
107
    contactMap.clear();
108
}
109

  
110
void MyDefaultContactManager::createContacts(const DetectionOutputMap& outputsMap)
111
{
112
    using core::CollisionModel;
113
    using core::collision::Contact;
114

  
115
    int nbContact = 0;
116

  
117
	double origineActuelle[3];
118

  
119

  
120
	// First iterate on the collision detection outputs and look for existing or new contacts
121
	for (DetectionOutputMap::const_iterator outputsIt = outputsMap.begin(),
122
		outputsItEnd = outputsMap.end(); outputsIt != outputsItEnd ; ++outputsIt)
123
	{
124
		const helper::set<int>& myGroup_first=outputsIt->first.first->getGroups();
125
		const helper::set<int>& myGroup_second=outputsIt->first.second->getGroups();
126
        if (aTouche.getValue()){
127
			helper::set<int>::iterator it_first=myGroup_first.begin();
128
			helper::set<int>::iterator it_second=myGroup_second.begin();
129
			if (*it_first == 1){
130
				origineActuelle[0] = outputsIt->first.first->getContext()->getMechanicalState()->getPX(0);
131
				origineActuelle[1] = outputsIt->first.first->getContext()->getMechanicalState()->getPY(0);
132
				origineActuelle[2] = outputsIt->first.first->getContext()->getMechanicalState()->getPZ(0);
133
                deepInMeristem.setValue(std::sqrt(pow(origine.getValue()[0]-origineActuelle[0],2)+pow(origine.getValue()[1]-origineActuelle[1],2)+pow(origine.getValue()[2]-origineActuelle[2],2)));
134
			}
135
			else if (*it_second==1){
136
				origineActuelle[0] = outputsIt->first.second->getContext()->getMechanicalState()->getPX(0);
137
				origineActuelle[1] = outputsIt->first.second->getContext()->getMechanicalState()->getPY(0);
138
				origineActuelle[2] = outputsIt->first.second->getContext()->getMechanicalState()->getPZ(0);
139
                deepInMeristem.setValue(std::sqrt(pow(origine.getValue()[0]-origineActuelle[0],2)+pow(origine.getValue()[1]-origineActuelle[1],2)+pow(origine.getValue()[2]-origineActuelle[2],2)));
140
			}
141
        }
142

  
143

  
144

  
145
		std::pair<ContactMap::iterator,bool> contactInsert =
146
			contactMap.insert(ContactMap::value_type(outputsIt->first,Contact::SPtr()));
147
		ContactMap::iterator contactIt = contactInsert.first;
148
		if (contactInsert.second)
149
		{
150
            // new contact
151
            //sout << "Creation new "<<contacttype<<" contact"<<sendl;
152
            CollisionModel* model1 = outputsIt->first.first;
153
            CollisionModel* model2 = outputsIt->first.second;
154
            std::string responseUsed = getContactResponse(model1, model2);
155

  
156

  
157
            if (*model1->getGroups().begin() == 1 && !aTouche.getValue()){
158
            if (!aTouche.getValue()){
159
                printf("Collision detected\n");
160
				std::fflush(stdout);
161

  
162
                aTouche.setValue(true);
163
                sofa::helper::vector<double> actuelorigine;
164
                actuelorigine.push_back(model1->getContext()->getMechanicalState()->getPX(0));
165
                actuelorigine.push_back(model1->getContext()->getMechanicalState()->getPY(0));
166
                actuelorigine.push_back(model1->getContext()->getMechanicalState()->getPZ(0));
167
                origine.setValue(actuelorigine);
168

  
169
            }
170
			}
171
            else if(*model2->getGroups().begin() == 1 && !aTouche.getValue()){
172
				printf("Collision detected\n");
173
				std::fflush(stdout);
174

  
175
                aTouche.setValue(true);
176
                sofa::helper::vector<double> actuelorigine;
177
                actuelorigine.push_back(model2->getContext()->getMechanicalState()->getPX(0));
178
                actuelorigine.push_back(model2->getContext()->getMechanicalState()->getPY(0));
179
                actuelorigine.push_back(model2->getContext()->getMechanicalState()->getPZ(0));
180
                origine.setValue(actuelorigine);
181
            }
182
		
183
			std::fflush(stdout);
184

  
185

  
186

  
187
            // We can create rules in order to not respond to specific collisions
188
            if (!responseUsed.compare("null"))
189
            {
190
				contactMap.erase(contactIt);
191
            }
192
			else
193
			{
194
				Contact::SPtr contact = Contact::Create(responseUsed, model1, model2, intersectionMethod,
195
					this->f_printLog.getValue());
196

  
197
				if (contact == NULL)
198
				{
199
					std::string model1class = model1->getClassName();
200
					std::string model2class = model2->getClassName();
201
					int count = ++errorMsgCount[std::make_pair(responseUsed,
202
						std::make_pair(model1class, model2class))];
203
					if (count <= 10)
204
					{
205
						serr << "Contact " << responseUsed << " between " << model1->getClassName()
206
							<< " and " << model2->getClassName() << " creation failed" << sendl;
207
						if (count == 1)
208
						{
209
							serr << "Supported models for contact " << responseUsed << ":" << sendl;
210
							for (Contact::Factory::const_iterator it =
211
								Contact::Factory::getInstance()->begin(),
212
								itend = Contact::Factory::getInstance()->end(); it != itend; ++it)
213
							{
214
								if (it->first != responseUsed) continue;
215
								serr << "   " << helper::gettypename(it->second->type()) << sendl;
216
							}
217
							serr << sendl;
218
						}
219
						if (count == 10) serr << "further messages suppressed" << sendl;
220
					}
221
					contactMap.erase(contactIt);
222
				}
223
				else
224
				{
225
					contactIt->second = contact;
226
					contact->setName(model1->getName() + std::string("-") + model2->getName());
227
					setContactTags(model1, model2, contact);
228
					contact->f_printLog.setValue(this->f_printLog.getValue());
229
					contact->init();
230
					contact->setDetectionOutputs(outputsIt->second);
231
					++nbContact;
232
				}
233
			}
234
		}
235
		else
236
		{
237
            // pre-existing and still active contact
238
            contactIt->second->setDetectionOutputs(outputsIt->second);
239
            ++nbContact;
240
		}
241
	}
242

  
243
	// Then look at previous contacts
244
	// and remove inactive contacts
245
	std::stack<ContactMap::iterator> deadContacts;
246
	for (ContactMap::iterator contactIt = contactMap.begin(), contactItEnd = contactMap.end();
247
		contactIt != contactItEnd;)
248
	{
249
		bool remove = false;
250
		DetectionOutputMap::const_iterator outputsIt = outputsMap.find(contactIt->first);
251
		if (outputsIt == outputsMap.end())
252
		{
253
            // inactive contact
254
            if (contactIt->second->keepAlive())
255
            {
256
				contactIt->second->setDetectionOutputs(NULL);
257
                ++nbContact;
258
            }
259
            else
260
            {
261
				remove = true;
262
			}
263
		}
264
		if (remove)
265
		{
266
			if (contactIt->second)
267
			{
268
                contactIt->second->removeResponse();
269
                contactIt->second->cleanup();
270
                contactIt->second.reset();
271
			}
272
			ContactMap::iterator eraseIt = contactIt;
273
			++contactIt;
274
			contactMap.erase(eraseIt);
275
		}
276
		else
277
		{
278
			++contactIt;
279
		}
280
	}
281

  
282
    // now update contactVec
283
    contacts.clear();
284
    contacts.reserve(nbContact);
285
    for (ContactMap::const_iterator contactIt = contactMap.begin(), contactItEnd = contactMap.end();
286
		contactIt != contactItEnd; ++contactIt)
287
    {
288
        contacts.push_back(contactIt->second);
289
    }
290

  
291
    // compute number of contacts attached to each collision model
292
    std::map< CollisionModel*, int > nbContactsMap;
293
    for (unsigned int i = 0; i < contacts.size(); ++i)
294
    {
295
        std::pair< CollisionModel*, CollisionModel* > cms = contacts[i]->getCollisionModels();
296
        nbContactsMap[cms.first]++;
297
        if (cms.second != cms.first)
298
            nbContactsMap[cms.second]++;
299
    }
300

  
301
	// TODO: this is VERY inefficient, should be replaced with a visitor
302
    helper::vector< CollisionModel* > collisionModels;
303
    simulation::Node* context = dynamic_cast< simulation::Node* >(getContext());
304
    context->getTreeObjects< CollisionModel >(&collisionModels);
305

  
306
    for (unsigned int i = 0; i < collisionModels.size(); ++i)
307
    {
308
        collisionModels[i]->setNumberOfContacts(nbContactsMap[collisionModels[i]]);
309
    }
310
}
311

  
312
std::string MyDefaultContactManager::getContactResponse(core::CollisionModel* model1, core::CollisionModel* model2)
313
{
314
    std::string responseUsed = response.getValue().getSelectedItem();
315
    std::string params = responseParams.getValue();
316
    if (!params.empty())
317
    {
318
        responseUsed += '?';
319
        responseUsed += params;
320
    }
321
    std::string response1 = model1->getContactResponse();
322
    std::string response2 = model2->getContactResponse();
323

  
324
    if (response1.empty()  &&  response2.empty()) return responseUsed;
325
    if (response1.empty()  && !response2.empty()) return response2;
326
    if (!response1.empty() &&  response2.empty()) return response1;
327

  
328
    if (response1 != response2) return responseUsed;
329
    else return response1;
330
}
331

  
332
void MyDefaultContactManager::draw(const core::visual::VisualParams* vparams)
333
{
334
    for (sofa::helper::vector<core::collision::Contact::SPtr>::iterator it = contacts.begin(); it!=contacts.end(); it++)
335
    {
336
        if ((*it)!=NULL)
337
            (*it)->draw(vparams);
338
    }
339
}
340

  
341
void MyDefaultContactManager::removeContacts(const ContactVector &c)
342
{
343
    ContactVector::const_iterator remove_it = c.begin();
344
    ContactVector::const_iterator remove_itEnd = c.end();
345

  
346
    ContactVector::iterator it;
347
    ContactVector::iterator itEnd;
348

  
349
    ContactMap::iterator map_it;
350
    ContactMap::iterator map_itEnd;
351

  
352
    while (remove_it != remove_itEnd)
353
    {
354
        // Whole scene contacts
355
        it = contacts.begin();
356
        itEnd = contacts.end();
357

  
358
        while (it != itEnd)
359
        {
360
            if (*it == *remove_it)
361
            {
362
                (*it)->removeResponse();
363
                (*it)->cleanup();
364
                it->reset();
365
                contacts.erase(it);
366
                break;
367
            }
368

  
369
            ++it;
370
        }
371

  
372
        // Stored contacts (keeping alive)
373
        map_it = contactMap.begin();
374
        map_itEnd = contactMap.end();
375

  
376
        while (map_it != map_itEnd)
377
        {
378
            if (map_it->second == *remove_it)
379
            {
380
                ContactMap::iterator erase_it = map_it;
381
                ++map_it;
382

  
383
                erase_it->second->removeResponse();
384
                erase_it->second->cleanup();
385
                erase_it->second.reset();
386
                contactMap.erase(erase_it);
387
            }
388
            else
389
            {
390
                ++map_it;
391
            }
392
        }
393

  
394
        ++remove_it;
395
    }
396
}
397

  
398
void MyDefaultContactManager::setContactTags(core::CollisionModel* model1, core::CollisionModel* model2, core::collision::Contact::SPtr contact)
399
{
400
    sofa::core::objectmodel::TagSet tagsm1 = model1->getTags();
401
    sofa::core::objectmodel::TagSet tagsm2 = model2->getTags();
402
    sofa::core::objectmodel::TagSet::iterator it;
403
    for(it=tagsm1.begin(); it != tagsm1.end(); it++)
404
        contact->addTag(*it);
405
    for(it=tagsm2.begin(); it!=tagsm2.end(); it++)
406
        contact->addTag(*it);
407
}
408

  
409
} // namespace collision
410

  
411
} // namespace component
412

  
413
} // namespace sofa
AFM/CMakeLists.txt (revision 1)
1
#cmake_minimum_required(VERSION 2.8)
2

  
3
include(${SOFA_CMAKE_DIR}/preProject.cmake)
4

  
5
set(HEADER_FILES
6
	
7
)
8

  
9
set(SOURCE_FILES
10

  
11
	AFM.cpp)
12
    
13
if(APPLE)
14

  
15
    set(RC_FILE "runSOFA.icns")
16

  
17
else()
18

  
19
    set(RC_FILE "sofa.rc")
20

  
21
endif()
22

  
23
add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES} ${RC_FILES})
24

  
25
AddLinkerDependencies(SofaGuiMain SofaComponentMain SofaPython Flexible AFM_plane)
26

  
27
ADD_DEFINITIONS(-DNDEBUG )
28
ADD_DEFINITIONS(-DBOOST_UBLAS_NDEBUG -O3)
29

  
30

  
31

  
32
if(SOFA-LIB_SIMULATION_GRAPH_DAG)
33
    AddLinkerDependencies(SofaSimulationGraph)
34
endif()
35

  
36
if(UNIX)
37

  
38
    AddLinkerDependencies("dl")
39

  
40
endif()
41
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LINK_LIBRARIES} )
42
include(${SOFA_CMAKE_DIR}/postProject.cmake)
43

  
AFM/AFM-results.txt (revision 1)
1
### E = 1000 ; P = 10 ; R = 0.4 = small ; mesh subsubsubdivided; first the force then the depth ###
2

  
AFM/AFM.cpp (revision 1)
1
#include <sofa/simulation/graph/DAGSimulation.h>
2
#include <plugins/SofaPython/SceneLoaderPY.h>
3
#include <sofa/helper/system/PluginManager.h>
4
#include <sofa/defaulttype/Mat.h>
5
#include <SofaBaseLinearSolver/FullVector.h>
6
#include <sofa/simulation/common/MechanicalVisitor.h>
7
#include <SofaComponentMain/init.h>
8
#include <../MyDefaultContactManager.h>
9
#include <sofa/core/objectmodel/BaseObject.h>
10
#include <SofaBoundaryCondition/ConstantForceField.h>
11
#include <sofa/simulation/common/FindByTypeVisitor.h>
12
#include <SofaBaseMechanics/MechanicalObject.h>
13
#include <sofa/helper/accessor.h>
14
#include <sofa/defaulttype/DataTypeInfo.h>
15
#include <SofaBoundaryCondition/ProjectToLineConstraint.h>
16
#include <cmath>
17
#include <cstdlib>
18
#include <fstream>
19
#include <vector>
20

  
21
using namespace sofa;
22
using namespace simulation;
23

  
24
typedef sofa::component::linearsolver::FullVector<double> FullVector;
25
typedef defaulttype::Vec3dTypes::Deriv Deriv;
26
typedef defaulttype::Vec3d myVec3d;
27

  
28
 /// return the maximum difference between corresponding entries, or the infinity if the vectors have different sizes
29
template< typename Vector1, typename Vector2>
30
static double vectorCompare( const Vector1& m1, const Vector2& m2 )
31
{
32
    if( m1.size()!=m2.size() ) {
33
         printf("Comparison between vectors of different sizes\n");
34
		 std::fflush(stdout);
35
        return std::numeric_limits<double>::infinity();
36
	}
37
    double result = 0;
38
    for( unsigned i=0; i<m1.size(); i++ ){
39
        double diff = fabs(m1.element(i)-m2.element(i));
40
        if( diff>result  ) result=diff;
41
    }
42
    return result;
43
}
44

  
45
 /** fill the vector with the positions.
46
      @param x the position vector
47
      */
48
void getAssembledPositionVector( FullVector* x, unsigned xSize, 
49
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
50
{
51
    x->resize(xSize);
52
	unsigned offset = 0;
53

  
54
	for (unsigned i = 0; i < DOFs.size(); i++){
55
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecCoord> > vSrc =  DOFs[i]->readPositions();
56

  
57
		for (unsigned j=0; j < vSrc.size(); j++){
58
			double tmp = 0.0;
59
            tmp = vSrc[j][0];
60
            //            defaulttype::Vec3dTypes::Coord getValue(vSrc[j], 0, tmp);
61
            x->set(offset + 3*j,tmp);
62
           // DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 1, tmp);
63
            tmp = vSrc[j][1];
64
            x->set(offset + 3*j+1,tmp);
65
            //DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 2, tmp);
66
            tmp = vSrc[j][2];
67
            x->set(offset + 3*j+2,tmp);
68
		}
69
		offset += DOFs[i]->getSize() * 3;
70
	}
71
}
72

  
73
    /** fill the vector with the velocities.
74
      @param v the velocity vector
75
      */
76
void getAssembledVelocityVector( FullVector* v, unsigned vSize, 
77
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
78
{
79
    v->resize(vSize);
80
	unsigned offset = 0;
81

  
82
	for (unsigned i = 0; i < DOFs.size(); i++){
83
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecDeriv> > vSrc =  DOFs[i]->readVelocities();
84
		for (unsigned j=0; j < vSrc.size(); j++){
85
			double tmp = 0.0;
86
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 0, tmp);
87
            tmp = vSrc[j][0];
88
            v->set(offset + 3*j,tmp);
89
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 1, tmp);
90
            tmp = vSrc[j][1];
91
            v->set(offset + 3*j+1,tmp);
92
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 2, tmp);
93
            tmp = vSrc[j][2];
94
            v->set(offset + 3*j+2,tmp);
95
		}
96
		offset += DOFs[i]->getSize() * 3;
97
	}
98
	
99
}
100

  
101

  
102
int main()
103
{
104
    //the file in which the resulting curve will be put
105
    std::ofstream fileResult("./AFM-results.txt");
106
    fileResult << "### first the force then the depth ###\n\n" ;
107

  
108
	//load the required plugins
109
    std::string pluginPath = "Flexible";
110
    std::string pluginPath1 = "AFM_plane";
111

  
112
    sofa::helper::system::PluginRepository.addLastPath("../../../../build_release/lib/");
113
    if (sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath) &&
114
            sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath1))
115
        sofa::helper::system::PluginManager::getInstance().init();
116

  
117

  
118

  
119
	unsigned xsize; ///< size of assembled position vector, 
120
    unsigned vsize; ///< size of assembled velocity vector, 
121

  
122

  
123
    // loading the scene which is in the file examples/AFM-plane.py
124
	setSimulation(new simulation::graph::DAGSimulation());
125
    sofa::component::init();
126
    Node::SPtr root = getSimulation()->createNewGraph("root");
127

  
128
	SceneLoaderPY LoaderPy;  
129
    root = LoaderPy.load("./AFM-plane.py");
130
	getSimulation()->init(root.get());
131

  
132
	//we take the direction of the force 
133
    sofa::component::forcefield::ConstantForceField<defaulttype::Vec3dTypes>::SPtr CFF;
134
	root->getContext()->get(CFF, sofa::core::objectmodel::BaseContext::SearchRoot);
135

  
136
	Deriv forceInit = CFF->force.getValue();
137

  
138
	Deriv forceActu;
139
	forceActu[0] = 0;
140
	forceActu[1] = 0;
141
	forceActu[2] = 0;
142
	CFF->force = forceActu;
143

  
144
	
145
	// first find the size of the DOFs
146
	core::ExecParams* params = core::ExecParams::defaultInstance();
147
    FindByTypeVisitor<component::container::MechanicalObject<defaulttype::Vec3dTypes> > FBTVisitor(params);
148
	root->execute(FBTVisitor);
149
	
150
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> allPoints;
151
	allPoints = FBTVisitor.found;
152

  
153
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs, mObject;
154
	for (unsigned i=0; i<allPoints.size();i++)
155
        if (allPoints[i]->getName() == "DOFs" || allPoints[i]->getName() == "indentor" )
156
			DOFs.push_back(allPoints[i]);
157

  
158
	for (unsigned i=0; i<allPoints.size();i++)
159
		if (allPoints[i]->getName() == "DOFs")
160
			mObject.push_back(allPoints[i]);
161
	
162
	unsigned xInitSize = mObject[0]->getSize();
163

  
164
	xsize = DOFs[0]->getSize() * DOFs[0]->getCoordDimension() +  DOFs[1]->getSize() * DOFs[1]->getCoordDimension();
165
	vsize = DOFs[0]->getMatrixSize() + DOFs[1]->getMatrixSize(); 
166

  
167
	FullVector x0, x1, v0, v1, xinit, xend;
168
    getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
169
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
170

  
171
    double dx, dv;
172
    unsigned n=0;
173
    const double  precision = 1.e-4;
174
	unsigned const nmax = 1000;
175
    // first loop to stabilize the plane growth under pressure
176
	
177
    do {
178
        getSimulation()->animate(root.get(),0.01);
179

  
180
        getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
181
        getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
182

  
183
        dx = vectorCompare(x0,x1);
184
        dv = vectorCompare(v0,v1);
185
        x0 = x1;
186
        v0 = v1;
187
        n++;
188

  
189
	} while((dx>precision || dv>precision) && n < nmax);           // 
190
	
191
    printf("\n %i iterations to stabilize the plane \n",n);
192
	std::fflush(stdout);
193

  
194
	getAssembledPositionVector(&xinit, xInitSize*3, mObject);
195

  
196
	//second loop : to detect a collision
197

  
198
	//we place the indentor first and calculate the force
199
	forceInit[0] = 0;
200
	forceInit[1] = 0;
201
    forceInit[2] = -0.1;
202
	
203
	
204

  
205
	//we put the position of indentor
206
    component::container::MechanicalObject<defaulttype::Vec3dTypes> *indentor = NULL ;
207
	if (DOFs[0]->getName()=="DOFs")
208
		indentor = DOFs[1];
209
	else indentor = DOFs[0];
210

  
211
	helper::vector<double> centerPos;
212

  
213
    centerPos.push_back(0.5);
214
    centerPos.push_back(0.5);
215
    centerPos.push_back(2);
216

  
217
	indentor->forcePointPosition(0,centerPos);
218

  
219
	myVec3d indentPos;
220
	myVec3d indentForce;
221
    indentPos.set(0.5 ,0.5, 2);
222
    indentForce.set(0,0,1);
223

  
224
    component::projectiveconstraintset::ProjectToLineConstraint<defaulttype::Vec3dTypes>::SPtr constraint;
225
	root->getContext()->get(constraint, sofa::core::objectmodel::BaseContext::SearchRoot);
226
	constraint->f_origin.setValue(indentPos);
227
	constraint->f_direction.setValue(indentForce);
228

  
229
    forceActu[2] = -0.1;
230

  
231
	CFF->force = forceActu;
232

  
233
	component::collision::MyDefaultContactManager::SPtr MDCM;
234
	root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
235
	while (!MDCM->CollisionDetected())
236
	{
237
		getSimulation()->animate(root.get(),0.01);
238
		root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
239
	}
240

  
241
	
242
	//third loop : until the end we increment the force
243
	n = 0;
244
	unsigned compteur = 0;
245

  
246
	getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
247
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
248
	
249

  
250
    while (forceActu.norm() < 150 &&  MDCM->getDepth() < 0.15 ){
251
		n = 0;
252
		fileResult << forceActu.norm() <<" " ;
253
		printf("new force %f : ",forceActu.norm());
254
		std::fflush(stdout);
255
		
256
		do {
257
			getSimulation()->animate(root.get(),0.01);
258

  
259
	        getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
260
		    getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
261

  
262
			dx = vectorCompare(x0,x1);
263
			dv = vectorCompare(v0,v1);
264
			x0 = x1;
265
		    v0 = v1;
266
			n++;
267

  
268
		} while((dx>precision || dv>precision) && n < nmax);           // 
269
		
270
        printf("%i iterations, depth: %f \n",n,MDCM->getDepth());
271
		std::fflush(stdout);
272

  
273
		compteur++;
274
		fileResult << MDCM->getDepth() << std::endl;
275
		forceActu += forceInit;
276
		CFF->force = forceActu;
277
	}
278

  
279

  
280

  
281
	//forth loop to decrement the force 
282

  
283
    /*while (forceActu.norm() > 0.1){
284
		n = 0;
285
		fileResult << forceActu.norm() <<" " ;
286
		printf("new force %f : ",forceActu.norm());
287
		std::fflush(stdout);
288
		
289
		do {
290
			getSimulation()->animate(root.get(),0.01);
291

  
292
	        getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
293
		    getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
294

  
295
			dx = vectorCompare(x0,x1);
296
			dv = vectorCompare(v0,v1);
297
			x0 = x1;
298
		    v0 = v1;
299
			n++;
300

  
301
		} while((dx>precision || dv>precision) && n < nmax);           // 
302
		
303
        printf("%i iterations, depth : %f \n",n,MDCM->getDepth() );
304
		std::fflush(stdout);
305

  
306
		compteur++;
307
		fileResult << MDCM->getDepth() << std::endl;
308
		forceActu -= forceInit;
309
		CFF->force = forceActu;
310
	}
311
	*/
312

  
313
	return 0;
314
}
315

  

Formats disponibles : Unified diff