@@ -128,7 +128,7 @@ bool IsoSurface::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThr
128128 if (closed != false )
129129 {
130130 VTmp = Plocal + Depth1 * Dlocal;
131- tmp = fn. Evaluate ( VTmp) - threshold ;
131+ tmp = EvaluatePolarized (fn, VTmp);
132132 if (Depth1 > accuracy)
133133 {
134134 if (tmp < 0.0 ) /* The ray hits the bounding shape */
@@ -149,12 +149,12 @@ bool IsoSurface::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThr
149149 {
150150 Depth1 = accuracy * 5.0 ;
151151 VTmp = Plocal + Depth1 * Dlocal;
152- if (fn. Evaluate ( VTmp) < threshold )
152+ if ( IsInside (fn, VTmp))
153153 Thread->isosurfaceData ->Inv3 = -1 ;
154154 /* Change the sign of the function (IPoint is in the bounding shpae.)*/
155155 }
156156 VTmp = Plocal + Depth2 * Dlocal;
157- if (fn. Evaluate ( VTmp) < threshold )
157+ if ( IsInside (fn, VTmp))
158158 {
159159 IPoint = ray.Evaluate (Depth2);
160160 if (Clip.empty () || Point_In_Clip (IPoint, Clip, Thread))
@@ -180,11 +180,11 @@ bool IsoSurface::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThr
180180 {
181181 /* IPoint is on the isosurface */
182182 VTmp = Plocal + tmin * Dlocal;
183- if ( fabs (fn. Evaluate (VTmp) - threshold ) < (maxg * accuracy * 4.0 ))
183+ if ( EvaluateAbs (fn, VTmp ) < (maxg * accuracy * 4.0 ))
184184 {
185185 tmin = accuracy * 5.0 ;
186186 VTmp = Plocal + tmin * Dlocal;
187- if (fn. Evaluate ( VTmp) < threshold )
187+ if ( IsInside (fn, VTmp))
188188 Thread->isosurfaceData ->Inv3 = -1 ;
189189 /* change the sign and go into the isosurface */
190190 }
@@ -213,6 +213,8 @@ bool IsoSurface::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThr
213213
214214 if (IFound)
215215 Thread->Stats ()[Ray_IsoSurface_Tests_Succeeded]++;
216+
217+ Thread->isosurfaceData ->pFn = NULL ;
216218 }
217219
218220 if (eval == true )
@@ -264,14 +266,34 @@ bool IsoSurface::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const
264266 if (!container->Inside (New_Point))
265267 return (Test_Flag (this , INVERTED_FLAG));
266268
267- if (GenericScalarFunctionInstance (Function, Thread).Evaluate (New_Point) > threshold)
269+ GenericScalarFunctionInstance fn (Function, Thread);
270+ if (!IsInside (fn, New_Point))
268271 return (Test_Flag (this , INVERTED_FLAG));
269272
270273 /* Inside the box. */
271274 return (!Test_Flag (this , INVERTED_FLAG));
272275}
273276
274277
278+ double IsoSurface::GetPotential (const Vector3d& globalPoint, bool subtractThreshold, TraceThreadData *pThread) const
279+ {
280+ Vector3d localPoint;
281+
282+ if (Trans != NULL )
283+ MInvTransPoint (localPoint, globalPoint, Trans);
284+ else
285+ localPoint = globalPoint;
286+
287+ double potential = GenericScalarFunctionInstance (Function, pThread).Evaluate (localPoint);
288+ if (subtractThreshold)
289+ potential -= threshold;
290+
291+ if (Test_Flag (this , INVERTED_FLAG))
292+ return -potential;
293+ else
294+ return potential;
295+ }
296+
275297
276298/* ****************************************************************************
277299*
@@ -345,6 +367,9 @@ void IsoSurface::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *
345367
346368 Result.normalize ();
347369 }
370+
371+ if (positivePolarity)
372+ Result.invert ();
348373 }
349374}
350375
@@ -513,7 +538,9 @@ void IsoSurface::Transform(const TRANSFORM* tr)
513538*
514539******************************************************************************/
515540
516- IsoSurface::IsoSurface () : ObjectBase(ISOSURFACE_OBJECT)
541+ IsoSurface::IsoSurface () :
542+ ObjectBase (ISOSURFACE_OBJECT),
543+ positivePolarity (false )
517544{
518545 container = shared_ptr<ContainedByShape>(new ContainedByBox ());
519546
@@ -588,6 +615,8 @@ ObjectPtr IsoSurface::Copy()
588615 // mark it as copy for use by max_gradient warning code
589616 New->isCopy = true ;
590617
618+ New->positivePolarity = positivePolarity;
619+
591620 New->container = shared_ptr<ContainedByShape>(container->Copy ());
592621
593622 return (New);
@@ -964,7 +993,31 @@ DBL IsoSurface::Float_Function(ISO_ThreadData& itd, DBL t) const
964993
965994 VTmp = itd.Pglobal + t * itd.Dglobal ;
966995
967- return ((DBL)itd.Inv3 * (itd.pFn ->Evaluate (VTmp) - threshold));
996+ return ((DBL)itd.Inv3 * EvaluatePolarized (*itd.pFn , VTmp));
997+ }
998+
999+
1000+ /* ****************************************************************************/
1001+
1002+ DBL IsoSurface::EvaluateAbs (GenericScalarFunctionInstance& fn, Vector3d& p) const
1003+ {
1004+ return fabs (threshold - fn.Evaluate (p));
1005+ }
1006+
1007+ DBL IsoSurface::EvaluatePolarized (GenericScalarFunctionInstance& fn, Vector3d& p) const
1008+ {
1009+ if (positivePolarity)
1010+ return threshold - fn.Evaluate (p);
1011+ else
1012+ return fn.Evaluate (p) - threshold;
1013+ }
1014+
1015+ bool IsoSurface::IsInside (GenericScalarFunctionInstance& fn, Vector3d& p) const
1016+ {
1017+ if (positivePolarity)
1018+ return threshold < fn.Evaluate (p);
1019+ else
1020+ return fn.Evaluate (p) < threshold;
9681021}
9691022
9701023}
0 commit comments