Skip to content

Instantly share code, notes, and snippets.

@jesterKing
Created October 5, 2018 11:51
Show Gist options
  • Save jesterKing/ed45420c3d388386850e1f83dd902a9d to your computer and use it in GitHub Desktop.
Save jesterKing/ed45420c3d388386850e1f83dd902a9d to your computer and use it in GitHub Desktop.
int ShootRayOnCollection(ON_3dPoint point, ON_3dVector direction,
const ON_SimpleArray<const ON_Geometry*>* pConstGeometryArray,
ON_SimpleArray<ON_3dPoint>* pPoints, int maxReflections)
{
int rc = 0;
// Currently only supports surfaces and breps with untrimmed faces.
// Add support for meshes and trimmed breps
int count = pConstGeometryArray?pConstGeometryArray->Count():0;
if( count<1 )
return 0;
ON_SimpleArray<const ON_SurfaceTreeNode*> snode_list(count);
for ( int i=0; i<count; i++ )
{
const ON_Geometry* pGeometry = (*pConstGeometryArray)[i];
const ON_Surface* surface = ON_Surface::Cast(pGeometry);
if ( surface )
{
const ON_SurfaceTree* stree = surface->SurfaceTree();
if ( stree )
snode_list.Append(stree);
continue;
}
const ON_Brep* brep = ON_Brep::Cast(pGeometry);
if( brep )
{
for( int fi=0; fi<brep->m_F.Count(); fi++ )
{
const ON_SurfaceTree* stree = brep->m_F[fi].SurfaceTree();
if( stree )
snode_list.Append(stree);
}
continue;
}
}
if( snode_list.Count()<1 )
return 0;
if( pPoints && maxReflections>0 && point.IsValid() && direction.Unitize() )
{
ON_RayShooter shooter;
ON_X_EVENT hit;
ON_3dPoint Q = point;
ON_3dVector R = direction;
for( int i=0; i<maxReflections; i++ )
{
memset(&hit,0,sizeof(hit));
ON_3dVector T = R;
if( !T.Unitize() )
break;
if( !shooter.Shoot(Q,T,snode_list,hit) )
break;
Q = hit.m_A[0];
pPoints->Append(Q);
if( !hit.m_snodeB[0] )
break;
ON_3dVector N = hit.m_B[1]; // surface normal
double d = -2.0*(N.x*T.x + N.y*T.y + N.z*T.z);
R.x = T.x + d*N.x;
R.y = T.y + d*N.y;
R.z = T.z + d*N.z;
d = hit.m_A[0].DistanceTo( hit.m_B[0] );
shooter.m_min_travel_distance = d;
if( shooter.m_min_travel_distance < 1.0e-8 )
shooter.m_min_travel_distance = 1.0e-8;
}
rc = pPoints->Count();
}
return rc;
}
CRhinoCommand::result CCommandRayShooter::RunCommand(const CRhinoCommandContext& context)
{
ON_3dPoint p(10.0, 10.0, 10.0);
ON_3dVector d(1, -1, -1);
const CRhinoObject* object = 0;
CRhinoObjectIterator it(CRhinoObjectIterator::normal_objects, CRhinoObjectIterator::active_objects);
it.SetObjectFilter(ON::object_type::brep_object | ON::object_type::surface_object);
ON_SimpleArray<const ON_Geometry*> obs;
for (object = it.First(); 0 != object; object = it.Next())
{
const ON_Geometry* geom = object->Geometry();
if (geom == nullptr) continue;
obs.Append(geom);
}
ON_SimpleArray<ON_3dPoint> pts;
int totalhits = ShootRayOnCollection(p, d, &obs, &pts, 1);
return CRhinoCommand::success;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment