From fd9dc19a3497db444f8f99aa6f5335ddc767f499 Mon Sep 17 00:00:00 2001 From: Daniel Richard G Date: Mon, 18 Nov 2013 02:31:23 -0500 Subject: [PATCH] Added the exposed/ library and demo program to the Autotools build The libslvs library and CDemo program can now be built by Autotools. A few code changes were needed for this: C++ comments in C code had to be converted, constraint.cpp required some massaging, and fltkutil.cpp needed a stub for InitHeaps(). --- Makefile.am | 2 +- configure.ac | 2 +- exposed/CDemo.c | 133 +++++++++++++++------------- exposed/Makefile.am | 36 ++++++++ exposed/{Makefile => Makefile.msvc} | 0 exposed/lib.cpp | 21 +++-- exposed/obj/t | 0 exposed/slvs.h | 129 ++++++++++++++------------- src/constraint.cpp | 5 +- src/fltk/fltkutil.cpp | 4 + 10 files changed, 202 insertions(+), 130 deletions(-) create mode 100644 exposed/Makefile.am rename exposed/{Makefile => Makefile.msvc} (100%) delete mode 100644 exposed/obj/t diff --git a/Makefile.am b/Makefile.am index 6f558653..35564b02 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I ac-aux -SUBDIRS = src +SUBDIRS = src exposed exposed = \ exposed/CDemo.c \ diff --git a/configure.ac b/configure.ac index 34b11587..0813f791 100644 --- a/configure.ac +++ b/configure.ac @@ -164,7 +164,7 @@ AC_SUBST([LIBSPNAV_LIBS]) ## Wrap it up ## -AC_CONFIG_FILES([Makefile src/Makefile]) +AC_CONFIG_FILES([Makefile exposed/Makefile src/Makefile]) AC_OUTPUT cat < +/*----------------------------------------------------------------------------- + * Some sample code for slvs.dll. We draw some geometric entities, provide + * initial guesses for their positions, and then constrain them. The solver + * calculates their new positions, in order to satisfy the constraints. + * + * Copyright 2008-2013 Jonathan Westhues. + *---------------------------------------------------------------------------*/ +#ifdef HAVE_CONFIG_H +# include +#endif +#ifdef WIN32 +# include +#endif #include +#include +#include +#ifdef HAVE_STDINT_H +# include +#endif #include "slvs.h" -Slvs_System sys; +static Slvs_System sys; -void *CheckMalloc(size_t n) +static void *CheckMalloc(size_t n) { void *r = malloc(n); if(!r) { @@ -22,30 +32,30 @@ void *CheckMalloc(size_t n) return r; } -//----------------------------------------------------------------------------- -// An example of a constraint in 3d. We create a single group, with some -// entities and constraints. -//----------------------------------------------------------------------------- -void Example3d(void) +/*----------------------------------------------------------------------------- + * An example of a constraint in 3d. We create a single group, with some + * entities and constraints. + *---------------------------------------------------------------------------*/ +static void Example3d(void) { - // This will contain a single group, which will arbitrarily number 1. - int g = 1; + /* This will contain a single group, which will arbitrarily number 1. */ + Slvs_hGroup g = 1; - // A point, initially at (x y z) = (10 10 10) + /* A point, initially at (x y z) = (10 10 10) */ sys.param[sys.params++] = Slvs_MakeParam(1, g, 10.0); sys.param[sys.params++] = Slvs_MakeParam(2, g, 10.0); sys.param[sys.params++] = Slvs_MakeParam(3, g, 10.0); sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); - // and a second point at (20 20 20) + /* and a second point at (20 20 20) */ sys.param[sys.params++] = Slvs_MakeParam(4, g, 20.0); sys.param[sys.params++] = Slvs_MakeParam(5, g, 20.0); sys.param[sys.params++] = Slvs_MakeParam(6, g, 20.0); sys.entity[sys.entities++] = Slvs_MakePoint3d(102, g, 4, 5, 6); - // and a line segment connecting them. + /* and a line segment connecting them. */ sys.entity[sys.entities++] = Slvs_MakeLineSegment(200, g, SLVS_FREE_IN_3D, 101, 102); - // The distance between the points should be 30.0 units. + /* The distance between the points should be 30.0 units. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 1, g, SLVS_C_PT_PT_DISTANCE, @@ -53,13 +63,13 @@ void Example3d(void) 30.0, 101, 102, 0, 0); - // Let's tell the solver to keep the second point as close to constant - // as possible, instead moving the first point. + /* Let's tell the solver to keep the second point as close to constant + * as possible, instead moving the first point. */ sys.dragged[0] = 4; sys.dragged[1] = 5; sys.dragged[2] = 6; - // Now that we have written our system, we solve. + /* Now that we have written our system, we solve. */ Slvs_Solve(&sys, g); if(sys.result == SLVS_RESULT_OKAY) { @@ -73,25 +83,25 @@ void Example3d(void) } } -//----------------------------------------------------------------------------- -// An example of a constraint in 2d. In our first group, we create a workplane -// along the reference frame's xy plane. In a second group, we create some -// entities in that group and dimension them. -//----------------------------------------------------------------------------- -void Example2d(void) +/*----------------------------------------------------------------------------- + * An example of a constraint in 2d. In our first group, we create a workplane + * along the reference frame's xy plane. In a second group, we create some + * entities in that group and dimension them. + *---------------------------------------------------------------------------*/ +static void Example2d(void) { - int g; + Slvs_hGroup g; double qw, qx, qy, qz; g = 1; - // First, we create our workplane. Its origin corresponds to the origin - // of our base frame (x y z) = (0 0 0) + /* First, we create our workplane. Its origin corresponds to the origin + * of our base frame (x y z) = (0 0 0) */ sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0); sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0); sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0); sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); - // and it is parallel to the xy plane, so it has basis vectors (1 0 0) - // and (0 1 0). + /* and it is parallel to the xy plane, so it has basis vectors (1 0 0) + * and (0 1 0). */ Slvs_MakeQuaternion(1, 0, 0, 0, 1, 0, &qw, &qx, &qy, &qz); sys.param[sys.params++] = Slvs_MakeParam(4, g, qw); @@ -102,12 +112,12 @@ void Example2d(void) sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102); - // Now create a second group. We'll solve group 2, while leaving group 1 - // constant; so the workplane that we've created will be locked down, - // and the solver can't move it. + /* Now create a second group. We'll solve group 2, while leaving group 1 + * constant; so the workplane that we've created will be locked down, + * and the solver can't move it. */ g = 2; - // These points are represented by their coordinates (u v) within the - // workplane, so they need only two parameters each. + /* These points are represented by their coordinates (u v) within the + * workplane, so they need only two parameters each. */ sys.param[sys.params++] = Slvs_MakeParam(11, g, 10.0); sys.param[sys.params++] = Slvs_MakeParam(12, g, 20.0); sys.entity[sys.entities++] = Slvs_MakePoint2d(301, g, 200, 11, 12); @@ -116,11 +126,11 @@ void Example2d(void) sys.param[sys.params++] = Slvs_MakeParam(14, g, 10.0); sys.entity[sys.entities++] = Slvs_MakePoint2d(302, g, 200, 13, 14); - // And we create a line segment with those endpoints. + /* And we create a line segment with those endpoints. */ sys.entity[sys.entities++] = Slvs_MakeLineSegment(400, g, 200, 301, 302); - // Now three more points. + /* Now three more points. */ sys.param[sys.params++] = Slvs_MakeParam(15, g, 100.0); sys.param[sys.params++] = Slvs_MakeParam(16, g, 120.0); sys.entity[sys.entities++] = Slvs_MakePoint2d(303, g, 200, 15, 16); @@ -133,12 +143,12 @@ void Example2d(void) sys.param[sys.params++] = Slvs_MakeParam(20, g, 115.0); sys.entity[sys.entities++] = Slvs_MakePoint2d(305, g, 200, 19, 20); - // And arc, centered at point 303, starting at point 304, ending at - // point 305. + /* And arc, centered at point 303, starting at point 304, ending at + * point 305. */ sys.entity[sys.entities++] = Slvs_MakeArcOfCircle(401, g, 200, 102, 303, 304, 305); - // Now one more point, and a distance + /* Now one more point, and a distance */ sys.param[sys.params++] = Slvs_MakeParam(21, g, 200.0); sys.param[sys.params++] = Slvs_MakeParam(22, g, 200.0); sys.entity[sys.entities++] = Slvs_MakePoint2d(306, g, 200, 21, 22); @@ -146,13 +156,13 @@ void Example2d(void) sys.param[sys.params++] = Slvs_MakeParam(23, g, 30.0); sys.entity[sys.entities++] = Slvs_MakeDistance(307, g, 200, 23); - // And a complete circle, centered at point 306 with radius equal to - // distance 307. The normal is 102, the same as our workplane. + /* And a complete circle, centered at point 306 with radius equal to + * distance 307. The normal is 102, the same as our workplane. */ sys.entity[sys.entities++] = Slvs_MakeCircle(402, g, 200, 306, 102, 307); - // The length of our line segment is 30.0 units. + /* The length of our line segment is 30.0 units. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 1, g, SLVS_C_PT_PT_DISTANCE, @@ -160,45 +170,46 @@ void Example2d(void) 30.0, 301, 302, 0, 0); - // And the distance from our line segment to the origin is 10.0 units. + /* And the distance from our line segment to the origin is 10.0 units. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 2, g, SLVS_C_PT_LINE_DISTANCE, 200, 10.0, 101, 0, 400, 0); - // And the line segment is vertical. + /* And the line segment is vertical. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 3, g, SLVS_C_VERTICAL, 200, 0.0, 0, 0, 400, 0); - // And the distance from one endpoint to the origin is 15.0 units. + /* And the distance from one endpoint to the origin is 15.0 units. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 4, g, SLVS_C_PT_PT_DISTANCE, 200, 15.0, 301, 101, 0, 0); -/* - // And same for the other endpoint; so if you add this constraint then - // the sketch is overconstrained and will signal an error. +#if 0 + /* And same for the other endpoint; so if you add this constraint then + * the sketch is overconstrained and will signal an error. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 5, g, SLVS_C_PT_PT_DISTANCE, 200, 18.0, - 302, 101, 0, 0); */ + 302, 101, 0, 0); +#endif /* 0 */ - // The arc and the circle have equal radius. + /* The arc and the circle have equal radius. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 6, g, SLVS_C_EQUAL_RADIUS, 200, 0.0, 0, 0, 401, 402); - // The arc has radius 17.0 units. + /* The arc has radius 17.0 units. */ sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 7, g, SLVS_C_DIAMETER, @@ -206,11 +217,11 @@ void Example2d(void) 17.0*2, 0, 0, 401, 0); - // If the solver fails, then ask it to report which constraints caused - // the problem. + /* If the solver fails, then ask it to report which constraints caused + * the problem. */ sys.calculateFaileds = 1; - // And solve. + /* And solve. */ Slvs_Solve(&sys, g); if(sys.result == SLVS_RESULT_OKAY) { @@ -253,7 +264,7 @@ int main(void) sys.failed = CheckMalloc(50*sizeof(sys.failed[0])); sys.faileds = 50; -// Example3d(); + /*Example3d();*/ for(;;) { Example2d(); sys.params = sys.constraints = sys.entities = 0; diff --git a/exposed/Makefile.am b/exposed/Makefile.am new file mode 100644 index 00000000..757b3787 --- /dev/null +++ b/exposed/Makefile.am @@ -0,0 +1,36 @@ +## exposed/Makefile.am + +AM_CPPFLAGS = -DLIBRARY -I$(top_srcdir)/src + +AM_LDFLAGS = -L. + +noinst_PROGRAMS = CDemo +noinst_LIBRARIES = libslvs.a + +CDemo_SOURCES = CDemo.c + +libslvs_a_SOURCES = \ + slvs.h \ + lib.cpp \ + ../src/util.cpp \ + ../src/entity.cpp \ + ../src/expr.cpp \ + ../src/constraint.cpp \ + ../src/constrainteq.cpp \ + ../src/system.cpp + +if HAVE_FLTK +CDemo_SOURCES += ../src/fltk/fltkutil.cpp +endif +if WIN32 +CDemo_SOURCES += ../src/win32/w32util.cpp +endif + +CDemo_LDADD = -lslvs $(FLTK_LDSTATICFLAGS) + +EXTRA_DIST = \ + DOC.txt \ + Makefile.msvc \ + VbDemo.vb + +## end exposed/Makefile.am diff --git a/exposed/Makefile b/exposed/Makefile.msvc similarity index 100% rename from exposed/Makefile rename to exposed/Makefile.msvc diff --git a/exposed/lib.cpp b/exposed/lib.cpp index 5ad45209..aa4721ff 100644 --- a/exposed/lib.cpp +++ b/exposed/lib.cpp @@ -9,16 +9,27 @@ #include "slvs.h" Sketch SK; -System SYS; +static System SYS; -int IsInit = 0; +static int IsInit = 0; void Group::GenerateEquations(IdList *l) { // Nothing to do for now. } -void DoMessageBox(char *str, int rows, int cols, bool error) +void CnfFreezeInt(uint32_t v, const char *name) { + abort(); +} + +uint32_t CnfThawInt(uint32_t v, const char *name) +{ + abort(); +} + +void DoMessageBox(const char *str, int rows, int cols, bool error) +{ + abort(); } extern "C" { @@ -185,7 +196,7 @@ default: dbp("bad constraint type %d", sc->type); return; SK.constraint.Add(&c); } - for(i = 0; i < arraylen(ssys->dragged); i++) { + for(i = 0; i < (int)arraylen(ssys->dragged); i++) { if(ssys->dragged[i]) { hParam hp = { ssys->dragged[i] }; SYS.dragged.Add(&hp); @@ -251,4 +262,4 @@ default: dbp("bad constraint type %d", sc->type); return; FreeAllTemporary(); } -} +} /* extern "C" */ diff --git a/exposed/obj/t b/exposed/obj/t deleted file mode 100644 index e69de29b..00000000 diff --git a/exposed/slvs.h b/exposed/slvs.h index 1712fbc7..f1ddbdf9 100644 --- a/exposed/slvs.h +++ b/exposed/slvs.h @@ -1,32 +1,40 @@ -//----------------------------------------------------------------------------- -// Data structures and prototypes for slvs.lib, a geometric constraint solver. -// -// See the comments in this file, the accompanying sample code that uses -// this library, and the accompanying documentation (DOC.txt). -// -// Copyright 2009-2013 Jonathan Westhues. -//----------------------------------------------------------------------------- +/*----------------------------------------------------------------------------- + * Data structures and prototypes for slvs.lib, a geometric constraint solver. + * + * See the comments in this file, the accompanying sample code that uses + * this library, and the accompanying documentation (DOC.txt). + * + * Copyright 2009-2013 Jonathan Westhues. + *---------------------------------------------------------------------------*/ #ifndef __SLVS_H #define __SLVS_H -#ifdef EXPORT_DLL -#define DLL __declspec( dllexport ) +#ifdef WIN32 +# ifdef EXPORT_DLL +# define DLL __declspec( dllexport ) +# else +# define DLL __declspec( dllimport ) +# endif #else -#define DLL __declspec( dllimport ) +# define DLL #endif #ifdef __cplusplus extern "C" { #endif +#if defined(WIN32) && !defined(HAVE_C99_INTEGER_TYPES) +typedef UINT32 uint32_t; +#endif + typedef uint32_t Slvs_hParam; typedef uint32_t Slvs_hEntity; typedef uint32_t Slvs_hConstraint; typedef uint32_t Slvs_hGroup; -// To obtain the 3d (not projected into a workplane) of a constraint or -// an entity, specify this instead of the workplane. +/* To obtain the 3d (not projected into a workplane) of a constraint or + * an entity, specify this instead of the workplane. */ #define SLVS_FREE_IN_3D 0 @@ -45,9 +53,9 @@ typedef struct { #define SLVS_E_DISTANCE 70000 -// The special point, normal, and distance types used for parametric step -// and repeat, extrude, and assembly are currently not exposed. Please -// contact us if you are interested in using these. +/* The special point, normal, and distance types used for parametric step + * and repeat, extrude, and assembly are currently not exposed. Please + * contact us if you are interested in using these. */ #define SLVS_E_WORKPLANE 80000 #define SLVS_E_LINE_SEGMENT 80001 @@ -125,16 +133,15 @@ typedef struct { typedef struct { - //// INPUT VARIABLES - // - // Here, we specify the parameters and their initial values, the entities, - // and the constraints. For example, param[] points to the array of - // parameters, which has length params, so that the last valid element - // is param[params-1]. - // - // param[] is actually an in/out variable; if the solver is successful, - // then the new values (that satisfy the constraints) are written to it. - // + /*** INPUT VARIABLES + * + * Here, we specify the parameters and their initial values, the entities, + * and the constraints. For example, param[] points to the array of + * parameters, which has length params, so that the last valid element + * is param[params-1]. + * + * param[] is actually an in/out variable; if the solver is successful, + * then the new values (that satisfy the constraints) are written to it. */ Slvs_Param *param; int params; Slvs_Entity *entity; @@ -142,39 +149,39 @@ typedef struct { Slvs_Constraint *constraint; int constraints; - // If a parameter corresponds to a point (distance, normal, etc.) being - // dragged, then specify it here. This will cause the solver to favor - // that parameter, and attempt to change it as little as possible even - // if that requires it to change other parameters more. - // - // Unused members of this array should be set to zero. + /* If a parameter corresponds to a point (distance, normal, etc.) being + * dragged, then specify it here. This will cause the solver to favor + * that parameter, and attempt to change it as little as possible even + * if that requires it to change other parameters more. + * + * Unused members of this array should be set to zero. */ Slvs_hParam dragged[4]; - // If the solver fails, then it can determine which constraints are - // causing the problem. But this is a relatively slow process (for - // a system with n constraints, about n times as long as just solving). - // If calculateFaileds is true, then the solver will do so, otherwise - // not. + /* If the solver fails, then it can determine which constraints are + * causing the problem. But this is a relatively slow process (for + * a system with n constraints, about n times as long as just solving). + * If calculateFaileds is true, then the solver will do so, otherwise + * not. */ int calculateFaileds; - //// OUTPUT VARIABLES - // - // If the solver fails, then it can report which constraints are causing - // the problem. The caller should allocate the array failed[], and pass - // its size in faileds. - // - // The solver will set faileds equal to the number of problematic - // constraints, and write their Slvs_hConstraints into failed[]. To - // ensure that there is sufficient space for any possible set of - // failing constraints, faileds should be greater than or equal to - // constraints. + /*** OUTPUT VARIABLES + * + * If the solver fails, then it can report which constraints are causing + * the problem. The caller should allocate the array failed[], and pass + * its size in faileds. + * + * The solver will set faileds equal to the number of problematic + * constraints, and write their Slvs_hConstraints into failed[]. To + * ensure that there is sufficient space for any possible set of + * failing constraints, faileds should be greater than or equal to + * constraints. */ Slvs_hConstraint *failed; int faileds; - // The solver indicates the number of unconstrained degrees of freedom. + /* The solver indicates the number of unconstrained degrees of freedom. */ int dof; - // The solver indicates whether the solution succeeded. + /* The solver indicates whether the solution succeeded. */ #define SLVS_RESULT_OKAY 0 #define SLVS_RESULT_INCONSISTENT 1 #define SLVS_RESULT_DIDNT_CONVERGE 2 @@ -185,12 +192,12 @@ typedef struct { DLL void Slvs_Solve(Slvs_System *sys, Slvs_hGroup hg); -// Our base coordinate system has basis vectors -// (1, 0, 0) (0, 1, 0) (0, 0, 1) -// A unit quaternion defines a rotation to a new coordinate system with -// basis vectors -// U V N -// which these functions compute from the quaternion. +/* Our base coordinate system has basis vectors + * (1, 0, 0) (0, 1, 0) (0, 0, 1) + * A unit quaternion defines a rotation to a new coordinate system with + * basis vectors + * U V N + * which these functions compute from the quaternion. */ DLL void Slvs_QuaternionU(double qw, double qx, double qy, double qz, double *x, double *y, double *z); DLL void Slvs_QuaternionV(double qw, double qx, double qy, double qz, @@ -198,16 +205,16 @@ DLL void Slvs_QuaternionV(double qw, double qx, double qy, double qz, DLL void Slvs_QuaternionN(double qw, double qx, double qy, double qz, double *x, double *y, double *z); -// Similarly, compute a unit quaternion in terms of two basis vectors. +/* Similarly, compute a unit quaternion in terms of two basis vectors. */ DLL void Slvs_MakeQuaternion(double ux, double uy, double uz, double vx, double vy, double vz, double *qw, double *qx, double *qy, double *qz); -//------------------------------------- -// These are just convenience functions, to save you the trouble of filling -// out the structures by hand. The code is included in the header file to -// let the compiler inline them if possible. +/*------------------------------------- + * These are just convenience functions, to save you the trouble of filling + * out the structures by hand. The code is included in the header file to + * let the compiler inline them if possible. */ static Slvs_Param Slvs_MakeParam(Slvs_hParam h, Slvs_hGroup group, double val) { diff --git a/src/constraint.cpp b/src/constraint.cpp index 95b3a1e5..dac581c4 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -60,7 +60,7 @@ void Constraint::DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA) { SK.constraint.ClearTags(); for(int i = 0; i < SK.constraint.n; i++) { - Constraint *ct = &(SK.constraint.elem[i]); + ConstraintBase *ct = &(SK.constraint.elem[i]); if(ct->type != type) continue; if(ct->entityA.v != entityA.v) continue; @@ -112,6 +112,8 @@ void Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { Entity::NO_ENTITY, Entity::NO_ENTITY, false, false); } +#ifndef LIBRARY + void Constraint::MenuConstrain(int id) { Constraint c; ZERO(&c); @@ -707,3 +709,4 @@ void Constraint::MenuConstrain(int id) { InvalidateGraphics(); } +#endif /* ! LIBRARY */ diff --git a/src/fltk/fltkutil.cpp b/src/fltk/fltkutil.cpp index ff541e67..b35a251a 100644 --- a/src/fltk/fltkutil.cpp +++ b/src/fltk/fltkutil.cpp @@ -105,3 +105,7 @@ void *MemAlloc(size_t n) { void MemFree(void *p) { free(p); } + +void InitHeaps(void) { + /* nothing to do */ +}