opensurgsim
KnotIdentificationBehavior.h
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2013-2016, SimQuest Solutions Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SURGSIM_BLOCKS_KNOTIDENTIFICATIONBEHAVIOR_H
17 #define SURGSIM_BLOCKS_KNOTIDENTIFICATIONBEHAVIOR_H
18 
19 #include <vector>
20 
22 #include "SurgSim/Math/Vector.h"
23 #include "SurgSim/Framework/Behavior.h"
24 
25 namespace SurgSim
26 {
27 namespace Physics
28 {
29 class Fem1DRepresentation;
30 }
31 }
32 
33 namespace SurgSim
34 {
35 namespace Blocks
36 {
46 {
47 public:
49  explicit KnotIdentificationBehavior(const std::string& name);
50 
52  void setFem1d(const std::shared_ptr<SurgSim::Framework::Component>& fem1d);
53 
55  const std::shared_ptr<SurgSim::Physics::Fem1DRepresentation>& getFem1d() const;
56 
58  const std::string& getKnotName();
59 
60  void update(double dt) override;
61  int getTargetManagerType() const override;
62  bool doInitialize() override;
63  bool doWakeUp() override;
64 
71  void addKnownKnotCode(const std::string& name, const std::vector<int>& code, const std::vector<int>& signs);
72 
74  void clearKnownKnotCodes();
75 
80  struct Crossing
81  {
83  int id;
84  size_t segmentId;
85  double segmentLocation;
86  int sign;
87  Crossing(int id, size_t segmentId, double segmentLocation, int sign)
88  : id(id), segmentId(segmentId), segmentLocation(segmentLocation), sign(sign) {}
89  bool operator==(const Crossing& rhs) const
90  {
91  return (id == rhs.id) && (segmentId == rhs.segmentId) && (segmentLocation == rhs.segmentLocation) &&
92  (sign == rhs.sign);
93  }
94  };
95 
96 protected:
98  std::map<std::string, std::vector<std::vector<Crossing>>> m_knownLists;
99 
102  std::string detectAndIdentifyKnot(const SurgSim::Math::Matrix33d& projection);
103 
106  std::vector<Crossing> getGaussCode(const SurgSim::Math::Matrix33d& projection);
107 
114  void buildNodeData(const Math::Vector3d& projectionX,
115  const Math::Vector3d& projectionY,
116  std::vector<SurgSim::Math::Vector3d>* nodes3d,
117  std::vector<SurgSim::Math::Vector2d>* nodes2d,
118  std::vector<SurgSim::Math::Vector3d>* segments3d);
119 
126  std::vector<Crossing> calculateCrossings(const Math::Vector3d& projectionZ,
127  const std::vector<SurgSim::Math::Vector3d>& nodes3d,
128  const std::vector<SurgSim::Math::Vector2d>& nodes2d,
129  const std::vector<SurgSim::Math::Vector3d>& segments3d);
130 
133  void performReidmeisterMoves(std::vector<Crossing>* gaussCode);
134 
139  bool tryReidmeisterMove1(std::vector<Crossing>* gaussCode, std::vector<int>* erased);
140 
145  bool tryReidmeisterMove2(std::vector<Crossing>* gaussCode, std::vector<int>* erased);
146 
149  {
150  std::vector<Crossing> code;
151  size_t i;
152  size_t iCount;
153  size_t m;
154  size_t n;
156  : i(std::numeric_limits<size_t>::max()), iCount(0),
157  m(std::numeric_limits<size_t>::max()), n(std::numeric_limits<size_t>::max()) {}
158  };
159 
164  bool tryReidmeisterMove3(std::vector<Crossing>* gaussCode, ReidmeisterMove3Data* data);
165 
168  void adjustGaussCodeForErasedCrossings(std::vector<Crossing>* gaussCode);
169 
173  std::string identifyKnot(const std::vector<Crossing>& gaussCode);
174 
176  std::shared_ptr<SurgSim::Physics::Fem1DRepresentation> m_fem1d;
177 
179  std::vector<SurgSim::Math::Matrix33d> m_projections;
180 
182  boost::mutex m_mutex;
183 
185  std::string m_knotName;
186 
187 private:
191  size_t nextIndex(const std::vector<Crossing>& code, size_t i);
192 
196  size_t prevIndex(const std::vector<Crossing>& code, size_t i);
197 
201  bool isSameSign(const std::vector<Crossing>& code, size_t i, size_t j);
202 
206  bool isSameCross(const std::vector<Crossing>& code, size_t i, size_t j);
207 
211  bool doesOverlap(const std::vector<Crossing>& code, size_t i, size_t j, size_t k, size_t l);
212 
215  void erase(std::vector<Crossing>* code, size_t i, size_t j);
216 
219  void erase(std::vector<Crossing>* code, size_t i, size_t j, size_t k, size_t l);
220 
224  size_t getComplementCross(const std::vector<Crossing>& code, size_t i);
225 
231  bool hasCommonNeighbor(const std::vector<Crossing>& code, size_t i, size_t j, size_t* k, size_t* l);
232 
235  bool isSameCode(const std::vector<Crossing>& code, const std::vector<Crossing>& knot);
236 };
237 
238 } // namespace Blocks
239 } // namespace SurgSim
240 
241 #endif // SURGSIM_BLOCKS_KNOTIDENTIFICATIONBEHAVIOR_H
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
struct with variables for tracking Reidmeister move 3.
Definition: KnotIdentificationBehavior.h:148
Eigen::Matrix< double, 3, 1 > Vector3d
A 3D vector of doubles.
Definition: Vector.h:57
int sign
also known as handedness. See documentation for addKnownKnotCode.
Definition: KnotIdentificationBehavior.h:86
int id
The gauss code. abs(id) indicates which crossing. sign(id) is positive for over and negative for unde...
Definition: KnotIdentificationBehavior.h:83
struct to store a Crossing.
Definition: KnotIdentificationBehavior.h:80
std::vector< SurgSim::Math::Matrix33d > m_projections
The list of projection matrices to try.
Definition: KnotIdentificationBehavior.h:179
Definitions of 2x2 and 3x3 rigid (isometric) transforms.
boost::mutex m_mutex
Mutex for the knot name.
Definition: KnotIdentificationBehavior.h:182
Definitions of small fixed-size vector types.
The KnotIdentificationBehavior detects and identifies a knot in a fem1d representation.
Definition: KnotIdentificationBehavior.h:45
Behaviors perform actions.
Definition: Behavior.h:40
std::map< std::string, std::vector< std::vector< Crossing > > > m_knownLists
Known knots, mapping the name to a vector of extended gauss codes.
Definition: KnotIdentificationBehavior.h:98
Eigen::Matrix< double, 3, 3, Eigen::RowMajor > Matrix33d
A 3x3 matrix of doubles.
Definition: Matrix.h:51
std::string m_knotName
The name of the knot that was detected.
Definition: KnotIdentificationBehavior.h:185
std::shared_ptr< SurgSim::Physics::Fem1DRepresentation > m_fem1d
The fem1d within which the knot is checked for.
Definition: KnotIdentificationBehavior.h:176