/*
* Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
* Applied Mathematics, Norway.
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of SISL.
*
* SISL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* SISL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with SISL. If not, see
* .
*
* In accordance with Section 7(b) of the GNU Affero General Public
* License, a covered work must retain the producer line in every data
* file that is created or manipulated using SISL.
*
* Other Usage
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial activities involving the SISL library without
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
*/
#include "sisl-copyright.h"
/*
*
* $Id: s1161.c,v 1.2 2001-03-19 15:58:41 afr Exp $
*
*/
#define S1161
#include "sislP.h"
#if defined(SISLNEEDPROTOTYPES)
void
s1161(SISLObject *po1,double *cmax,double aepsge,SISLIntdat **pintdat,int *jstat)
#else
void s1161(po1,cmax,aepsge,pintdat,jstat)
SISLObject *po1;
double *cmax;
double aepsge;
SISLIntdat **pintdat;
int *jstat;
#endif
/*
*********************************************************************
*
*********************************************************************
*
* PURPOSE : Find all maximum points of an onedimentional object (of type
* point, curve or surface). The maximum points found has to
* be greater or equal to the level value cmax .
* In this rouine the outer edges/endpoints of the objects
* are treated.
*
*
*
* INPUT : po1 - The object.
* aepsge - Geometry resolution.
*
*
*
* INPUT/OUTPUT:
* cmax - The level value.
*
* OUTPUT : pintdat - Maximum points found.
* jstat - status messages
* = 1 : Maximumpoints found equal to level value
* = 2 : Maximumpoints found over level value
* = 0 : no maximum
* < 0 : error
*
*
* METHOD : This function is treating point maximum.
* Otherwise it is computing edge/endpoint maximum
* by recurson on the edges.
* The maxima in the inner of the object is found by
* calling another recursiv function.
* REFERENCES :
*
*-
* CALLS : s6err - Gives error message.
* s1435 - Pick edge curve from a surface.
* s1438 - Pick endpoint from a curve.
* s1162 - Find the intersections in the inner of the objects.
* s1190 - A boxtest.
* s6idnpt - Put a new intpt to given intdat.
* s6idput - Put contence of one intdat in an other intdat.
* s6idlis - Compute list elements from given intdat.
* s6idedg - Uppdate an edge from given intdat.
* freeEdge - Free space occupied by given edge.
* freePoint - Free space occupied by given point.
* freeCurve - Free space occupied by given curve.
* freeObject - Free space occupied by given object.
* freeIntdat - Free space occupied by given intdat.
* newEdge - Create new edge-structure.
* newIntpt - Create new maximum point-structure.
* newObject - Create new object.
*
* WRITTEN BY : Ulf J. Krystad , 05.89.
*
*********************************************************************
*/
{
int klevel=0; /* Parameter into s1162 */
int knum=0; /* Parameter into s1162 */
int kpar; /* Fixed parameter direction. */
int ki; /* Counter. */
int kedge; /* Number of edges. */
int idim = 1; /* Local dimension, always = 1 */
int kstat = 0; /* Local status variable. */
int kpos = 0; /* Position of error. */
double tpar; /* Help variable used for parameter value
and geometric distance. */
SISLEdge *qedge[2]; /* Edges for use in s1162(). */
SISLObject *qdum = SISL_NULL; /* Dummy pointer. */
SISLObject *qob = SISL_NULL; /* Objects for use in recurson. */
SISLIntdat *qintdat = SISL_NULL; /* Intdat for use in recurson. */
qedge[0] = SISL_NULL;
qedge[1] = SISL_NULL;
if (po1->iobj == SISLPOINT)
{
/* It's a point, treat the case here and return. */
/* Control the dimension. */
if (po1->p1->idim != idim ) goto err106;
/* Computing the distance beetween the point and level value. */
tpar = po1->p1->ecoef[0] - *cmax;
if (fabs(tpar) <= aepsge)
/* The point is close enough to the level value to be a max. */
*jstat = 1; /* Mark maximum found. */
else if (tpar > (double)0.0)
{
/* The point is greater than the level value . */
*jstat = 2; /* Mark new maximum found. */
*cmax = po1->p1->ecoef[0];
}
else
*jstat = 0; /* Mark no maximum found. */
if ( *jstat > 0 )
{
SISLIntpt *qt;
/* Add maximum point. */
qt = newIntpt(0,cmax,DZERO);
if (qt == SISL_NULL) goto err101;
/* Uppdate pintdat. */
s6idnpt(pintdat,&qt,1,&kstat);
if (kstat < 0) goto error;
}
}
else if (po1->iobj > SISLPOINT)
{
/* It's a higher order geometry, treat the edges here and
use a recursiv function to treat the inner of the object */
*jstat = 0;
/* Perform a boxtest */
s1190(po1,cmax,aepsge,&kstat);
if (kstat == 1) goto out;
/*Create a dummy object, to be used when calling
the intersection routines
treating two objects.*/
if ((qdum = newObject(SISLPOINT)) == SISL_NULL) goto err101;
kedge = 2 * po1->iobj;
kpar = kedge/2;
/* Create correct number of edges. */
if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101;
for (ki=0; kiiobj - 1)) == SISL_NULL) goto err101;
if (po1->iobj == SISLCURVE)
/* Pick out end point from a curve. */
s1438(po1->c1,ki,&(qob->p1),&tpar,&kstat);
else if (po1->iobj == SISLSURFACE)
/* Pick out edge curve from a surface. */
s1435(po1->s1,ki,&(qob->c1),&tpar,&kstat);
else
/* Unknown higher order object . */
goto err121;
if (kstat < 0) goto error;
/* Recursiv computing of end maximum. */
s1161(qob,cmax,aepsge,&qintdat,&kstat);
if (kstat < 0) goto error;
if (kstat == 2)
{
/* New maximum found, delete old ones */
if (*pintdat != SISL_NULL)
{
freeIntdat(*pintdat);
*pintdat = SISL_NULL;
}
if (qedge[0] != SISL_NULL)
{
/* Empty the edges */
freeEdge(qedge[0]);
if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101;
}
}
if (kstat)
{
/* Maximum found, add them to the list */
*jstat = max(*jstat,kstat); /* Mark maximum found. */
/* Put maximum found on edges into pintdat. */
/* Set parameter border values of object. */
s6idput(pintdat,qintdat,kpar,tpar,&kstat);
if (kstat < 0) goto error;
/* Uppdate edge structure. */
s6idedg(po1,qdum,1,kpar+1,tpar,*pintdat,
&(qedge[0]->prpt[ki]),&(qedge[0]->ipoint),&kstat);
if (kstat < 0) goto error;
}
if (qintdat != SISL_NULL) freeIntdat(qintdat);
qintdat = SISL_NULL;
freeObject(qob);
}
/* ---------------------------------------------------------------*/
/* Treat the inner of higher order objects. */
/* Before we enter internal maximum and subdivision we
initiate pointers to top level objects. */
if (po1->o1 == SISL_NULL) po1->o1 = po1;
/* Find the maximums in the inner of the object. */
s1162(po1,cmax,aepsge,pintdat,qedge,klevel,knum,&kstat);
if (kstat < 0) goto error;
*jstat = max(*jstat,kstat);
/* Organize the list in pintdat. */
s6idlis(po1,po1,pintdat,&kstat);
if (kstat < 0) goto error;
}
else
/* Unknown object . */
goto err121;
goto out;
/* -------------- ERROR HANDLING ----------------------------------------*/
/* Error in space allocation. */
err101: *jstat = -101;
s6err("s1161",*jstat,kpos);
goto out;
/* Error. Dimensions conflicting. */
err106: *jstat = -106;
s6err("s1161",*jstat,kpos);
goto out;
/* Error. Kind of object does not exist. */
err121: *jstat = -121;
s6err("s1161",*jstat,kpos);
goto out;
/* Error in lower order routine. */
error : *jstat = kstat;
s6err("s1161",*jstat,kpos);
goto out;
out:
/* Free the edges used in s1162. */
if (qedge[0] != SISL_NULL) freeEdge(qedge[0]);
/* Free the dummy object(point). */
if (qdum != SISL_NULL) freeObject(qdum);
}