Salome HOME
28c2a5ef3d9e2fba475badabbd43bfd1d192aacc
[tools/configuration.git] / config / patches / planegcs.001_for_shaper.patch
1 From 853a0a438422d61cf1b9756d6949e04e5270d495 Mon Sep 17 00:00:00 2001
2 From: azv <azv@opencascade.com>
3 Date: Thu, 2 Aug 2018 11:32:16 +0300
4 Subject: [PATCH] Update PlaneGCS solver for SHAPER needs
5
6 * Add possibility to compile PlaneGCS as a shared library
7 * Possibility to avoid memory clearance inside the solver (make possible external memory management)
8 ---
9  src/Mod/Sketcher/App/planegcs/Constraints.h | 48 ++++++++---------
10  src/Mod/Sketcher/App/planegcs/GCS.cpp       | 81 +++++++++++++++++++++++------
11  src/Mod/Sketcher/App/planegcs/GCS.h         |  8 +--
12  src/Mod/Sketcher/App/planegcs/Geo.h         | 34 ++++++------
13  src/Mod/Sketcher/App/planegcs/Util.h        | 10 ++++
14  5 files changed, 123 insertions(+), 58 deletions(-)
15
16 diff --git a/src/Mod/Sketcher/App/planegcs/Constraints.h b/src/Mod/Sketcher/App/planegcs/Constraints.h
17 index 559f3a2..76e4763 100644
18 --- a/src/Mod/Sketcher/App/planegcs/Constraints.h
19 +++ b/src/Mod/Sketcher/App/planegcs/Constraints.h
20 @@ -91,7 +91,7 @@ namespace GCS
21          HyperbolaNegativeMinorY = 17
22      };
23  
24 -    class Constraint
25 +    class PLANEGCS_EXPORT Constraint
26      {
27      _PROTECTED_UNLESS_EXTRACT_MODE_:
28          VEC_pD origpvec; // is used only as a reference for redirecting and reverting pvec
29 @@ -128,7 +128,7 @@ namespace GCS
30      };
31  
32      // Equal
33 -    class ConstraintEqual : public Constraint
34 +    class PLANEGCS_EXPORT ConstraintEqual : public Constraint
35      {
36      private:
37          inline double* param1() { return pvec[0]; }
38 @@ -142,7 +142,7 @@ namespace GCS
39      };
40  
41      // Difference
42 -    class ConstraintDifference : public Constraint
43 +    class PLANEGCS_EXPORT ConstraintDifference : public Constraint
44      {
45      private:
46          inline double* param1() { return pvec[0]; }
47 @@ -157,7 +157,7 @@ namespace GCS
48      };
49  
50      // P2PDistance
51 -    class ConstraintP2PDistance : public Constraint
52 +    class PLANEGCS_EXPORT ConstraintP2PDistance : public Constraint
53      {
54      private:
55          inline double* p1x() { return pvec[0]; }
56 @@ -178,7 +178,7 @@ namespace GCS
57      };
58  
59      // P2PAngle
60 -    class ConstraintP2PAngle : public Constraint
61 +    class PLANEGCS_EXPORT ConstraintP2PAngle : public Constraint
62      {
63      private:
64          inline double* p1x() { return pvec[0]; }
65 @@ -200,7 +200,7 @@ namespace GCS
66      };
67  
68      // P2LDistance
69 -    class ConstraintP2LDistance : public Constraint
70 +    class PLANEGCS_EXPORT ConstraintP2LDistance : public Constraint
71      {
72      private:
73          inline double* p0x() { return pvec[0]; }
74 @@ -224,7 +224,7 @@ namespace GCS
75      };
76  
77      // PointOnLine
78 -    class ConstraintPointOnLine : public Constraint
79 +    class PLANEGCS_EXPORT ConstraintPointOnLine : public Constraint
80      {
81      private:
82          inline double* p0x() { return pvec[0]; }
83 @@ -246,7 +246,7 @@ namespace GCS
84      };
85  
86      // PointOnPerpBisector
87 -    class ConstraintPointOnPerpBisector : public Constraint
88 +    class PLANEGCS_EXPORT ConstraintPointOnPerpBisector : public Constraint
89      {
90      private:
91          inline double* p0x() { return pvec[0]; }
92 @@ -268,7 +268,7 @@ namespace GCS
93      };
94  
95      // Parallel
96 -    class ConstraintParallel : public Constraint
97 +    class PLANEGCS_EXPORT ConstraintParallel : public Constraint
98      {
99      private:
100          inline double* l1p1x() { return pvec[0]; }
101 @@ -291,7 +291,7 @@ namespace GCS
102      };
103  
104      // Perpendicular
105 -    class ConstraintPerpendicular : public Constraint
106 +    class PLANEGCS_EXPORT ConstraintPerpendicular : public Constraint
107      {
108      private:
109          inline double* l1p1x() { return pvec[0]; }
110 @@ -315,7 +315,7 @@ namespace GCS
111      };
112  
113      // L2LAngle
114 -    class ConstraintL2LAngle : public Constraint
115 +    class PLANEGCS_EXPORT ConstraintL2LAngle : public Constraint
116      {
117      private:
118          inline double* l1p1x() { return pvec[0]; }
119 @@ -342,7 +342,7 @@ namespace GCS
120      };
121  
122      // MidpointOnLine
123 -    class ConstraintMidpointOnLine : public Constraint
124 +    class PLANEGCS_EXPORT ConstraintMidpointOnLine : public Constraint
125      {
126      private:
127          inline double* l1p1x() { return pvec[0]; }
128 @@ -366,7 +366,7 @@ namespace GCS
129      };
130  
131      // TangentCircumf
132 -    class ConstraintTangentCircumf : public Constraint
133 +    class PLANEGCS_EXPORT ConstraintTangentCircumf : public Constraint
134      {
135      private:
136          inline double* c1x() { return pvec[0]; }
137 @@ -389,7 +389,7 @@ namespace GCS
138          virtual double grad(double *);
139      };
140      // PointOnEllipse
141 -    class ConstraintPointOnEllipse : public Constraint
142 +    class PLANEGCS_EXPORT ConstraintPointOnEllipse : public Constraint
143      {
144      private:
145          inline double* p1x() { return pvec[0]; }
146 @@ -411,7 +411,7 @@ namespace GCS
147          virtual double grad(double *);
148      };
149      
150 -    class ConstraintEllipseTangentLine : public Constraint
151 +    class PLANEGCS_EXPORT ConstraintEllipseTangentLine : public Constraint
152      {
153      private:
154          Line l;
155 @@ -426,7 +426,7 @@ namespace GCS
156          virtual double grad(double *);
157      };
158          
159 -    class ConstraintInternalAlignmentPoint2Ellipse : public Constraint
160 +    class PLANEGCS_EXPORT ConstraintInternalAlignmentPoint2Ellipse : public Constraint
161      {
162      public:
163          ConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType);
164 @@ -442,7 +442,7 @@ namespace GCS
165          InternalAlignmentType AlignmentType;
166      };
167  
168 -    class ConstraintInternalAlignmentPoint2Hyperbola : public Constraint
169 +    class PLANEGCS_EXPORT ConstraintInternalAlignmentPoint2Hyperbola : public Constraint
170      {
171      public:
172          ConstraintInternalAlignmentPoint2Hyperbola(Hyperbola &e, Point &p1, InternalAlignmentType alignmentType);
173 @@ -458,7 +458,7 @@ namespace GCS
174          InternalAlignmentType AlignmentType;
175      };
176  
177 -    class ConstraintEqualMajorAxesConic : public Constraint
178 +    class PLANEGCS_EXPORT ConstraintEqualMajorAxesConic : public Constraint
179      {
180      private:
181          MajorRadiusConic * e1;
182 @@ -473,7 +473,7 @@ namespace GCS
183          virtual double grad(double *);
184      };
185  
186 -    class ConstraintEqualFocalDistance : public Constraint
187 +    class PLANEGCS_EXPORT ConstraintEqualFocalDistance : public Constraint
188      {
189      private:
190          ArcOfParabola * e1;
191 @@ -488,7 +488,7 @@ namespace GCS
192          virtual double grad(double *);
193      };
194  
195 -    class ConstraintCurveValue : public Constraint
196 +    class PLANEGCS_EXPORT ConstraintCurveValue : public Constraint
197      {
198      private:
199          inline double* pcoord() { return pvec[2]; } //defines, which coordinate of point is being constrained by this constraint
200 @@ -515,7 +515,7 @@ namespace GCS
201      };
202      
203      // PointOnHyperbola
204 -    class ConstraintPointOnHyperbola : public Constraint
205 +    class PLANEGCS_EXPORT ConstraintPointOnHyperbola : public Constraint
206      {
207      private:
208          inline double* p1x() { return pvec[0]; }
209 @@ -538,7 +538,7 @@ namespace GCS
210      };
211  
212      // PointOnParabola
213 -    class ConstraintPointOnParabola : public Constraint
214 +    class PLANEGCS_EXPORT ConstraintPointOnParabola : public Constraint
215      {
216      private:
217          void errorgrad(double* err, double* grad, double *param); //error and gradient combined. Values are returned through pointers.
218 @@ -558,7 +558,7 @@ namespace GCS
219          virtual double grad(double *);
220      };
221      
222 -    class ConstraintAngleViaPoint : public Constraint
223 +    class PLANEGCS_EXPORT ConstraintAngleViaPoint : public Constraint
224      {
225      private:
226          inline double* angle() { return pvec[0]; };
227 @@ -583,7 +583,7 @@ namespace GCS
228          virtual double grad(double *);
229      };
230  
231 -    class ConstraintSnell : public Constraint //snell's law angles constrainer. Point needs to lie on all three curves to be constraied.
232 +    class PLANEGCS_EXPORT ConstraintSnell : public Constraint //snell's law angles constrainer. Point needs to lie on all three curves to be constraied.
233      {
234      private:
235          inline double* n1() { return pvec[0]; };
236 diff --git a/src/Mod/Sketcher/App/planegcs/GCS.cpp b/src/Mod/Sketcher/App/planegcs/GCS.cpp
237 index 474024a..9103653 100644
238 --- a/src/Mod/Sketcher/App/planegcs/GCS.cpp
239 +++ b/src/Mod/Sketcher/App/planegcs/GCS.cpp
240 @@ -101,11 +101,56 @@
241  #endif
242  
243  #include <FCConfig.h>
244 +#ifndef _GCS_USE_STL_OUTPUT
245  #include <Base/Console.h>
246 +#endif
247  
248  #include <boost/graph/adjacency_list.hpp>
249  #include <boost/graph/connected_components.hpp>
250  
251 +namespace GCS
252 +{
253 +  void Log(const char* message)
254 +  {
255 +#ifdef _GCS_USE_STL_OUTPUT
256 +    std::cout << message << std::endl;
257 +#else
258 +    Base::Console().Log(message);
259 +#endif
260 +  }
261 +
262 +  void Log(const char* format, const char* param)
263 +  {
264 +#ifdef _GCS_USE_STL_OUTPUT
265 +    static char message[4096];
266 +    sprintf(message, format, param);
267 +    std::cout << message << std::endl;
268 +#else
269 +    Base::Console().Log(format, param);
270 +#endif
271 +  }
272 +
273 +  void Log(const char* format, const size_t param)
274 +  {
275 +#ifdef _GCS_USE_STL_OUTPUT
276 +    static char message[4096];
277 +    sprintf(message, format, param);
278 +    std::cout << message << std::endl;
279 +#else
280 +    Base::Console().Log(format, param);
281 +#endif
282 +}
283 +
284 +  void Warning(const char* message)
285 +  {
286 +#ifdef _GCS_USE_STL_OUTPUT
287 +    std::cout << "Warning: " << message << std::endl;
288 +#else
289 +    Base::Console().Warning(message);
290 +#endif
291 +  }
292 +}
293 +
294  typedef Eigen::FullPivHouseholderQR<Eigen::MatrixXd>::IntDiagSizeVectorType MatrixIndexType;
295  
296  #ifdef _GCS_DEBUG
297 @@ -130,7 +175,7 @@ void LogMatrix(std::string str, Eigen::MatrixXd matrix )
298  #else
299      const std::string tmp = stream.str();
300  
301 -    Base::Console().Log(tmp.c_str());
302 +    GCS::Log(tmp.c_str());
303  #endif
304  }
305  
306 @@ -155,7 +200,7 @@ void LogMatrix(std::string str, MatrixIndexType matrix )
307      #else
308      const std::string tmp = stream.str();
309  
310 -    Base::Console().Log(tmp.c_str());
311 +    GCS::Log(tmp.c_str());
312      #endif
313  }
314  #endif
315 @@ -178,7 +223,7 @@ void LogString(std::string str)
316      #else
317      const std::string tmp = stream.str();
318  
319 -    Base::Console().Log(tmp.c_str());
320 +    GCS::Log(tmp.c_str());
321      #endif
322  }
323  
324 @@ -429,7 +474,11 @@ void System::clear()
325  
326      reference.clear();
327      clearSubSystems();
328 +#ifdef _GCS_DO_NOT_FREE_CONSTRAINTS_MEMORY
329 +    clist.clear();
330 +#else
331      free(clist);
332 +#endif
333      c2p.clear();
334      p2c.clear();
335  }
336 @@ -486,9 +535,11 @@ void System::removeConstraint(Constraint *constr)
337      }
338      c2p.erase(constr);
339  
340 +#ifndef _GCS_DO_NOT_FREE_CONSTRAINTS_MEMORY
341      std::vector<Constraint *> constrvec;
342      constrvec.push_back(constr);
343      free(constrvec);
344 +#endif
345  }
346  
347  // basic constraints
348 @@ -1477,7 +1528,7 @@ int System::solve_BFGS(SubSystem *subsys, bool /*isFine*/, bool isRedundantsolvi
349                  << ", maxIter: "            << maxIterNumber  << "\n";
350  
351          const std::string tmp = stream.str();
352 -        Base::Console().Log(tmp.c_str());
353 +        GCS::Log(tmp.c_str());
354      }
355  
356      double divergingLim = 1e6*err + 1e12;
357 @@ -1493,7 +1544,7 @@ int System::solve_BFGS(SubSystem *subsys, bool /*isFine*/, bool isRedundantsolvi
358                          << ", h_norm: "           << h_norm  << "\n";
359  
360                  const std::string tmp = stream.str();
361 -                Base::Console().Log(tmp.c_str());
362 +                GCS::Log(tmp.c_str());
363              }
364              break;
365          }
366 @@ -1505,7 +1556,7 @@ int System::solve_BFGS(SubSystem *subsys, bool /*isFine*/, bool isRedundantsolvi
367                          << ", divergingLim: "            << divergingLim  << "\n";
368  
369                  const std::string tmp = stream.str();
370 -                Base::Console().Log(tmp.c_str());
371 +                GCS::Log(tmp.c_str());
372              }
373              break;
374          }
375 @@ -1542,7 +1593,7 @@ int System::solve_BFGS(SubSystem *subsys, bool /*isFine*/, bool isRedundantsolvi
376                      << ", h_norm: "                 << h_norm << "\n";
377  
378              const std::string tmp = stream.str();
379 -            Base::Console().Log(tmp.c_str());
380 +            GCS::Log(tmp.c_str());
381          }
382      }
383  
384 @@ -1598,7 +1649,7 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving)
385                  << ", maxIter: "        << maxIterNumber  << "\n";
386  
387          const std::string tmp = stream.str();
388 -        Base::Console().Log(tmp.c_str());
389 +        GCS::Log(tmp.c_str());
390      }
391  
392      double nu=2, mu=0;
393 @@ -1712,7 +1763,7 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving)
394                      << ", h_norm: "                 << h_norm << "\n";
395  
396              const std::string tmp = stream.str();
397 -            Base::Console().Log(tmp.c_str());
398 +            GCS::Log(tmp.c_str());
399          }
400      }
401  
402 @@ -1757,7 +1808,7 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving)
403                  << ", maxIter: "        << maxIterNumber  << "\n";
404  
405          const std::string tmp = stream.str();
406 -        Base::Console().Log(tmp.c_str());
407 +        GCS::Log(tmp.c_str());
408      }
409  
410      Eigen::VectorXd x(xsize), x_new(xsize);
411 @@ -1912,7 +1963,7 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving)
412                      << ", err(divergingLim): "  << err  << "\n";
413  
414              const std::string tmp = stream.str();
415 -            Base::Console().Log(tmp.c_str());
416 +            GCS::Log(tmp.c_str());
417          }
418  
419          // count this iteration and start again
420 @@ -1926,7 +1977,7 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving)
421          stream  << "DL: stopcode: "     << stop << ((stop == 1) ? ", Success" : ", Failed") << "\n";
422  
423          const std::string tmp = stream.str();
424 -        Base::Console().Log(tmp.c_str());
425 +        GCS::Log(tmp.c_str());
426      }
427  
428      return (stop == 1) ? Success : Failed;
429 @@ -3721,7 +3772,7 @@ int System::diagnose(Algorithm alg)
430      Eigen::SparseQR<Eigen::SparseMatrix<double>, Eigen::COLAMDOrdering<int> > SqrJT;
431  #else
432      if(qrAlgorithm==EigenSparseQR){
433 -        Base::Console().Warning("SparseQR not supported by you current version of Eigen. It requires Eigen 3.2.2 or higher. Falling back to Dense QR\n");
434 +        GCS::Warning("SparseQR not supported by you current version of Eigen. It requires Eigen 3.2.2 or higher. Falling back to Dense QR\n");
435          qrAlgorithm=EigenDenseQR;
436      }
437  #endif
438 @@ -4074,7 +4125,7 @@ int System::diagnose(Algorithm alg)
439                          break;
440                  }
441  
442 -                Base::Console().Log("Sketcher::RedundantSolving-%s-\n",solvername.c_str());
443 +                GCS::Log("Sketcher::RedundantSolving-%s-\n",solvername.c_str());
444              }
445  
446              if (res == Success) {
447 @@ -4088,7 +4139,7 @@ int System::diagnose(Algorithm alg)
448                  resetToReference();
449  
450                  if(debugMode==Minimal || debugMode==IterationLevel) {
451 -                    Base::Console().Log("Sketcher Redundant solving: %d redundants\n",redundant.size());
452 +                    GCS::Log("Sketcher Redundant solving: %d redundants\n",redundant.size());
453                  }
454  
455                  std::vector< std::vector<Constraint *> > conflictGroupsOrig=conflictGroups;
456 diff --git a/src/Mod/Sketcher/App/planegcs/GCS.h b/src/Mod/Sketcher/App/planegcs/GCS.h
457 index 17d57c8..ecc5b04 100644
458 --- a/src/Mod/Sketcher/App/planegcs/GCS.h
459 +++ b/src/Mod/Sketcher/App/planegcs/GCS.h
460 @@ -69,7 +69,7 @@ namespace GCS
461          IterationLevel = 2
462      };
463  
464 -    class System
465 +    class PLANEGCS_EXPORT System
466      {
467      // This is the main class. It holds all constraints and information
468      // about partitioning into subsystems and solution strategies
469 @@ -283,9 +283,9 @@ namespace GCS
470      // Helper elements
471      ///////////////////////////////////////
472  
473 -    void free(VEC_pD &doublevec);
474 -    void free(std::vector<Constraint *> &constrvec);
475 -    void free(std::vector<SubSystem *> &subsysvec);
476 +    PLANEGCS_EXPORT void free(VEC_pD &doublevec);
477 +    PLANEGCS_EXPORT void free(std::vector<Constraint *> &constrvec);
478 +    PLANEGCS_EXPORT void free(std::vector<SubSystem *> &subsysvec);
479  
480  } //namespace GCS
481  
482 diff --git a/src/Mod/Sketcher/App/planegcs/Geo.h b/src/Mod/Sketcher/App/planegcs/Geo.h
483 index 1cdb983..6246f3b 100644
484 --- a/src/Mod/Sketcher/App/planegcs/Geo.h
485 +++ b/src/Mod/Sketcher/App/planegcs/Geo.h
486 @@ -26,16 +26,20 @@
487  #include <cmath>
488  #include "Util.h"
489  
490 +#ifdef _MSC_VER
491 +#pragma warning(disable : 4251)
492 +#endif
493 +
494  namespace GCS
495  {
496 -    class DependentParameters 
497 +    class PLANEGCS_EXPORT DependentParameters
498      {
499      public:
500          DependentParameters():hasDependentParameters(false) {}
501          bool hasDependentParameters;
502      };
503      
504 -    class Point : public DependentParameters
505 +    class PLANEGCS_EXPORT Point : public DependentParameters
506      {
507      public:
508          Point(){x = 0; y = 0;}
509 @@ -55,7 +59,7 @@ namespace GCS
510      ///manually as well. The class also provides a bunch of methods to do math
511      ///on it (and derivatives are calculated implicitly).
512      ///
513 -    class DeriVector2
514 +    class PLANEGCS_EXPORT DeriVector2
515      {
516      public:
517          DeriVector2(){x=0; y=0; dx=0; dy=0;}
518 @@ -95,7 +99,7 @@ namespace GCS
519      // Geometries
520      ///////////////////////////////////////
521  
522 -    class Curve: public DependentParameters //a base class for all curve-based objects (line, circle/arc, ellipse/arc)
523 +    class PLANEGCS_EXPORT Curve: public DependentParameters //a base class for all curve-based objects (line, circle/arc, ellipse/arc)
524      {
525      public:
526          virtual ~Curve(){}
527 @@ -125,7 +129,7 @@ namespace GCS
528          virtual Curve* Copy() = 0; //DeepSOIC: I haven't found a way to simply copy a curve object provided pointer to a curve object.
529      };
530  
531 -    class Line: public Curve
532 +    class PLANEGCS_EXPORT Line: public Curve
533      {
534      public:
535          Line(){}
536 @@ -139,7 +143,7 @@ namespace GCS
537          virtual Line* Copy();
538      };
539  
540 -    class Circle: public Curve
541 +    class PLANEGCS_EXPORT Circle: public Curve
542      {
543      public:
544          Circle(){rad = 0;}
545 @@ -153,7 +157,7 @@ namespace GCS
546          virtual Circle* Copy();
547      };
548  
549 -    class Arc: public Circle
550 +    class PLANEGCS_EXPORT Arc: public Circle
551      {
552      public:
553          Arc(){startAngle=0;endAngle=0;rad=0;}
554 @@ -169,7 +173,7 @@ namespace GCS
555          virtual Arc* Copy();
556      };
557      
558 -    class MajorRadiusConic: public Curve
559 +    class PLANEGCS_EXPORT MajorRadiusConic: public Curve
560      {
561      public:
562          virtual ~MajorRadiusConic(){}
563 @@ -179,7 +183,7 @@ namespace GCS
564          DeriVector2 CalculateNormal(Point &p, double* derivparam = 0) = 0;
565      };
566      
567 -    class Ellipse: public MajorRadiusConic
568 +    class PLANEGCS_EXPORT Ellipse: public MajorRadiusConic
569      {
570      public:
571          Ellipse(){ radmin = 0;}
572 @@ -197,7 +201,7 @@ namespace GCS
573          virtual Ellipse* Copy();
574      };
575      
576 -    class ArcOfEllipse: public Ellipse
577 +    class PLANEGCS_EXPORT ArcOfEllipse: public Ellipse
578      {
579      public:
580          ArcOfEllipse(){startAngle=0;endAngle=0;radmin = 0;}
581 @@ -215,7 +219,7 @@ namespace GCS
582          virtual ArcOfEllipse* Copy();
583      };
584      
585 -    class Hyperbola: public MajorRadiusConic
586 +    class PLANEGCS_EXPORT Hyperbola: public MajorRadiusConic
587      {
588      public:
589          Hyperbola(){ radmin = 0;}
590 @@ -233,7 +237,7 @@ namespace GCS
591          virtual Hyperbola* Copy();
592      };    
593  
594 -    class ArcOfHyperbola: public Hyperbola
595 +    class PLANEGCS_EXPORT ArcOfHyperbola: public Hyperbola
596      {
597      public:
598          ArcOfHyperbola(){startAngle=0;endAngle=0;radmin = 0;}
599 @@ -249,7 +253,7 @@ namespace GCS
600          virtual ArcOfHyperbola* Copy();
601      };
602      
603 -    class Parabola: public Curve
604 +    class PLANEGCS_EXPORT Parabola: public Curve
605      {
606      public:
607          Parabola(){ }
608 @@ -263,7 +267,7 @@ namespace GCS
609          virtual Parabola* Copy();
610      };    
611  
612 -    class ArcOfParabola: public Parabola
613 +    class PLANEGCS_EXPORT ArcOfParabola: public Parabola
614      {
615      public:
616          ArcOfParabola(){startAngle=0;endAngle=0;}
617 @@ -279,7 +283,7 @@ namespace GCS
618          virtual ArcOfParabola* Copy();
619      };
620  
621 -    class BSpline: public Curve
622 +    class PLANEGCS_EXPORT BSpline: public Curve
623      {
624      public:
625          BSpline(){periodic=false;degree=2;}
626 diff --git a/src/Mod/Sketcher/App/planegcs/Util.h b/src/Mod/Sketcher/App/planegcs/Util.h
627 index 8a759ba..7baafaa 100644
628 --- a/src/Mod/Sketcher/App/planegcs/Util.h
629 +++ b/src/Mod/Sketcher/App/planegcs/Util.h
630 @@ -44,4 +44,14 @@ namespace GCS
631  
632  } //namespace GCS
633  
634 +#if defined WIN32
635 +#  if defined PLANEGCS_EXPORTS
636 +#    define PLANEGCS_EXPORT __declspec(dllexport)
637 +#  else
638 +#    define PLANEGCS_EXPORT __declspec(dllimport)
639 +#  endif
640 +#else
641 +#  define PLANEGCS_EXPORT
642 +#endif
643 +
644  #endif // PLANEGCS_UTIL_H
645 -- 
646 2.9.0.windows.1
647