Proposed sytem for parametrics and constraint implementation by Dawn Thomas (homovulgaris)

Provision for Parametrics and constraints greatly improves the performance of a Computer Aided Design System both in terms of geometry generation as well as analysis. Considering the unix model of division into multiple tools and libraries for individual functions as well as the fact that parametric/constraint functionalities are **not critical** elements in terms of geometry generation and raytracing, a logical solution would be the implemenation of a separate library (libpg)

libpg adds the following provisions to BRL-CAD system

- Creation & Modification of parameter-based geometry objects
- Creation of constraints between geometry objects
- Creation & Storage of Parametric Objects (non-geometric)
- Modification of geometry objects in .g files to indicate parametric nature

Part 1 would include building parametric objects based on existing non-parametric geometry objects as well as generation of purely parametric geometry. libpg acts as a library which sits above librt using the librt methods for creation and modification of geometry

A constraint system can be looked upon as a system of variables, their associated domains and set of constraints/relationships between the variables.

Fundamentally this can be visualised using a constraint network which is a 3-tuple.For a mathematical review please see ( Constraint Networks by Dawn Thomas ). Further we can have a graph based visualization of the same using vertices as variables and edges connecting vertices as constraints. It would be intuitive only for networks having binary (between two variables) or unary (constraints on self) constraints. Otherwise, one has to visualize hypergraphs which contain hyperedges which is basically a line connecting multiple vertices for example.

Implementation of the above constraint network in the BRL-CAD system, involves 3 fundamental aspects.

- Domain extraction
- Solution
- Geometry updation

Prerequisites for such a state is of course

- "Handle" generation and storage
- Updated geometry storage

A typical constraint solution operation is shown below.

An object oriented method of implementation would be the creation of a mixed ( in the sense that they contain both geometric and non-geometric information ) object. The object architecture is as shown below which shows the data types as well as the public and private methods.

From an Object Oriented point of view the major advantages is in terms of the structuring of data and in particular the system of calling methods or procedures. In effect each object knows how to evaluate equations within its space. For example a line or a curve **knows** ( has a method to ) calculate and return the coordinates of a point with a certain parameter value in its space ( a point at 0.6 ratio of length of the curve) With this value ( coordinates) thus returned and with the existing knowledge ( parent: curveid , parameter value:0.6 ) a parametric point object has the methods to instantiate it and store it.

The above method is efficient and useful only in the generation, modification and analysis of new geometry based on existing parametric/ non-parametric geometry. The evaluation method for constraints between already existing independent geometry would require special constraint objects. The effective difference between these objects and the earlier arises from the fact that generation of the parametric geometric objects depend on parametrics whereas constraints may or may not be feasible and thus evaluation would result in multiple solutions and they represent relationship between two independently defined elements ( parametrically or not )

Two major aspects of integration with librt are

- Database I/O
- Declaration/ Extraction of parameters/variables from respective rt_*_internal structures

Since most of the database input-output presently is completely handled by librt, it is expedient to use the same convention for writing the new non-geometric constraint object to the database. This is achieved through the pc_constraint_export and pc_constraint_import functions which are called by such functions as wdb_export or rt_db_put_internal via a new functab entry in table.c Or in more detail the steps taken to achieve these are

- Definition of ID_CONSTRAINT (39) in raytrace.h ( corresponding increment to ID_MAXIMUM)
- Creation of a corresponding entry to functab array in table.c
- Addition of pc_constraint_export,pc_constraint_import and pc_constraint_ifree functions

Regarding the declaration or extraction of parameters, the method of approach is to use a callback function rt_functab. Associated with each existing element we add a rt_*_params function which is called via the functab. This would declare the list of parameters it is built on as well as the list of implicit constraints on these parameters if any ( for example in the case of an ellipse there are 4 parameters: 1 point - center, 3 vectors-a,b,c and associated constraints ). This data is stored as a pc_pc_set (ParameterConstraint Set) This way, after the implementation of libpc we can remove most of the code from existing rt_*_prep functions which do such implicit constraint checking handling the same via libpc

- Addition of rt_*_params to the RT_DECLARE_INTERFACE macro in table.c
- Addition to the functab table in table.c
- Definition of corresponding function is various primitives/*.c files

**What should be the convention for naming the parameters ? Also there is a certain issue in the sense that some of the geometry are special cases of more generic geometry. So for a sphere we are concerned with only radius and center where as it is defined using ( point center) and 3 vectors (a b c). Should we name the parameter radius make 3 fastf_t * to a[0], b[1], and c[2] Or should we make 3 vectp_t to a,b,c or make 1 fast_t* to a[0], doing a further check/constraint that a[0]=b[1]=c[2] ?**

The datastructures necessary for the exchange of information (pc_pc_set which itself is built using a constraint set structure and parameter set structure) are defined currently in raytrace.h (Shift to pc.h in future? )

June 10th: The idea is to implement a constraint network using graph representation of boost c++ library. From the solvers point of view the constraint network would be composed of the following ( which are class definitions in pc_solver.h file)

- Constraint Network: A Graph composed of vertices being parameters and edges being constraint relations. The difference from the normal graph is in the sense that an edge (or hyperedge ) maybe connecting more than two vertices.
- Parameter Object: Vertex of the graph:
- Pointers to various constraints it is connected to

- Constraint Object: Edge/Hyperedge of the graph - Relation between parameters
- Pointers to the parameters int the particular relation
- Relation : Basic representation of the relationship
- Relation Stack : The stack based representation of the relationship

- Parameter Object: Vertex of the graph:

The action of the Solver object/method is the production of a Solution Class A Solution is basically an instantiation of parameters along with their possible values or an instantiation of the form ( param1= value, param2=value and so on) In this case the value is basically a region of the domain the parameter could occupy.

- Option A: If a particular parameter has a domain(0.5<x<2.5) This can be viewed as the existance for two unary constraints on the parameter x ( x>0.5 and x<2.5 )
- Option B: Utilization of a Domain class which basically is dynamic array of individual domains ( by individual domain I imply a [min,max] region )

For example consider parameter set p1,p2,p3 The solution maybe

- (p1, 0.5-1.5; p2, 0.2) : P3 can have any value if P2 =0.2 and P1 lies in the range [0.1,1.5]
- (p1, 1.8; p2, 0.3-0.8; p3, 0.3-0.9) : P1=1.8, and P2 lies in the range [0.3,0.8] and P3 in the range [0.3,0.9]
- (p1, 2.3; p2, 2.2; p3, 1.4) : Unique solution P1=2.3, P2=2.2, P3=1.4

Modus operandi:

- Import data and create pc_pc_set using rt_*_params functions via rt_functab
- Run a domain extractor on the constraint objects in pc_set
- Generate the constraint network
- Call Solver

Initial draft/intent

It would be ideal to provide both analytical and numeric evaluation methods the second one being of primary importance in terms of constraint based calculations. Considering the standard methods of parametrization ( see Enumeration below ) I think the implementation of an analytic solving system would be easier. Though for the solution of more complex equation as well as majority of constraints , libpg will have to provide support for numerical solutions.

*Various standard methods of parametrics and constraints available in CAD Programs ( CATIA as a case study )*

- Point
- Coordinates
- On Curve
- On Plane
- On Surface
- Circle/Sphere Centre
- Tangent on Curve
- Between (2 points)
- Extremum
- Extremum Polar

- Line
- Point-Point
- Point-Direction
- Angle/Normal to the curve
- Tangent to the Curve
- Normal to the surface
- Bisecting

- Plane
- Offset from plane
- Parallel through Point
- Angle/Normal to Plane
- Three points
- Two Lines
- Point and Line
- Planar Curve
- Normal to Curve
- Tangent to Surface
- Equation
- Mean through points

- Axis
- Polyline
- Circle
- Corner
- Connect Curve
- Conic
- Spline
- Helix
- Spiral

- Distance
- Length
- Angle
- Radius/Diameter
- Semimajor axis
- Semiminor axis
- Symmetry
- Midpoint
- Equidistant point
- Fix
- Coincidence
- Cocentricity
- Tangency
- Parallelism
- Perpendicular
- Horizontal
- Vertical
- Angle with axis