black ifcclash

This commit is contained in:
htlcnn
2020-11-01 19:23:15 +07:00
committed by Dion Moult
parent d6881e833d
commit 892be5444c
2 changed files with 146 additions and 196 deletions
+36 -88
View File
@@ -29,10 +29,7 @@ class ContactData(object):
The contact in question.
"""
self.names = names
self._inds = {
names[0]: contact.b1,
names[1]: contact.b2
}
self._inds = {names[0]: contact.b1, names[1]: contact.b2}
self._point = contact.pos
self.raw = contact
@@ -83,14 +80,8 @@ class DistanceData(object):
The distance query result.
"""
self.names = set(names)
self._inds = {
names[0]: result.b1,
names[1]: result.b2
}
self._points = {
names[0]: result.nearest_points[0],
names[1]: result.nearest_points[1]
}
self._inds = {names[0]: result.b1, names[1]: result.b2}
self._points = {names[0]: result.nearest_points[0], names[1]: result.nearest_points[1]}
self._distance = result.min_distance
@property
@@ -149,7 +140,7 @@ class CollisionManager(object):
Initialize a mesh-mesh collision manager.
"""
if fcl is None:
raise ValueError('No FCL Available!')
raise ValueError("No FCL Available!")
# {name: {geom:, obj}}
self._objs = {}
# {id(bvh) : str, name}
@@ -162,10 +153,7 @@ class CollisionManager(object):
self._manager = fcl.DynamicAABBTreeCollisionManager()
self._manager.setup()
def add_object(self,
name,
mesh,
transform=None):
def add_object(self, name, mesh, transform=None):
"""
Add an object to the collision manager.
@@ -187,7 +175,7 @@ class CollisionManager(object):
transform = np.eye(4)
transform = np.asanyarray(transform, dtype=np.float64)
if transform.shape != (4, 4):
raise ValueError('transform must be (4,4)!')
raise ValueError("transform must be (4,4)!")
# create or recall from cache BVH
bvh = self._get_BVH(mesh)
@@ -198,8 +186,7 @@ class CollisionManager(object):
# Add collision object to set
if name in self._objs:
self._manager.unregisterObject(self._objs[name])
self._objs[name] = {'obj': o,
'geom': bvh}
self._objs[name] = {"obj": o, "geom": bvh}
# store the name of the geometry
self._names[id(bvh)] = name
@@ -217,14 +204,14 @@ class CollisionManager(object):
The identifier for the object
"""
if name in self._objs:
self._manager.unregisterObject(self._objs[name]['obj'])
self._manager.update(self._objs[name]['obj'])
self._manager.unregisterObject(self._objs[name]["obj"])
self._manager.update(self._objs[name]["obj"])
# remove objects from _objs
geom_id = id(self._objs.pop(name)['geom'])
geom_id = id(self._objs.pop(name)["geom"])
# remove names
self._names.pop(geom_id)
else:
raise ValueError('{} not in collision manager!'.format(name))
raise ValueError("{} not in collision manager!".format(name))
def set_transform(self, name, transform):
"""
@@ -239,18 +226,14 @@ class CollisionManager(object):
A new homogeneous transform matrix for the object
"""
if name in self._objs:
o = self._objs[name]['obj']
o = self._objs[name]["obj"]
o.setRotation(transform[:3, :3])
o.setTranslation(transform[:3, 3])
self._manager.update(o)
else:
raise ValueError('{} not in collision manager!'.format(name))
raise ValueError("{} not in collision manager!".format(name))
def in_collision_single(self,
mesh,
transform=None,
return_names=False,
return_data=False):
def in_collision_single(self, mesh, transform=None, return_names=False, return_data=False):
"""
Check a single object for collisions against all objects in the
manager.
@@ -288,9 +271,7 @@ class CollisionManager(object):
# Collide with manager's objects
cdata = fcl.CollisionData()
if return_names or return_data:
cdata = fcl.CollisionData(request=fcl.CollisionRequest(
num_max_contacts=100000,
enable_contact=True))
cdata = fcl.CollisionData(request=fcl.CollisionRequest(num_max_contacts=100000, enable_contact=True))
self._manager.collide(o, cdata, fcl.defaultCollisionCallback)
result = cdata.result.is_collision
@@ -305,7 +286,7 @@ class CollisionManager(object):
cg = contact.o2
name = self._extract_name(cg)
names = (name, '__external')
names = (name, "__external")
if cg == contact.o2:
names = reversed(names)
@@ -349,8 +330,7 @@ class CollisionManager(object):
"""
cdata = fcl.CollisionData()
if return_names or return_data:
cdata = fcl.CollisionData(request=fcl.CollisionRequest(
num_max_contacts=1000000, enable_contact=True))
cdata = fcl.CollisionData(request=fcl.CollisionRequest(num_max_contacts=1000000, enable_contact=True))
self._manager.collide(cdata, fcl.defaultCollisionCallback)
@@ -360,8 +340,7 @@ class CollisionManager(object):
contact_data = []
if return_names or return_data:
for contact in cdata.result.contacts:
names = (self._extract_name(contact.o1),
self._extract_name(contact.o2))
names = (self._extract_name(contact.o1), self._extract_name(contact.o2))
if return_names:
objs_in_collision.add(tuple(sorted(names)))
@@ -377,8 +356,7 @@ class CollisionManager(object):
else:
return result
def in_collision_other(self, other_manager,
return_names=False, return_data=False):
def in_collision_other(self, other_manager, return_names=False, return_data=False):
"""
Check if any object from this manager collides with any object
from another manager.
@@ -408,13 +386,8 @@ class CollisionManager(object):
"""
cdata = fcl.CollisionData()
if return_names or return_data:
cdata = fcl.CollisionData(
request=fcl.CollisionRequest(
num_max_contacts=100000,
enable_contact=True))
self._manager.collide(other_manager._manager,
cdata,
fcl.defaultCollisionCallback)
cdata = fcl.CollisionData(request=fcl.CollisionRequest(num_max_contacts=100000, enable_contact=True))
self._manager.collide(other_manager._manager, cdata, fcl.defaultCollisionCallback)
result = cdata.result.is_collision
objs_in_collision = set()
@@ -422,11 +395,9 @@ class CollisionManager(object):
if return_names or return_data:
for contact in cdata.result.contacts:
reverse = False
names = (self._extract_name(contact.o1),
other_manager._extract_name(contact.o2))
names = (self._extract_name(contact.o1), other_manager._extract_name(contact.o2))
if names[0] is None:
names = (self._extract_name(contact.o2),
other_manager._extract_name(contact.o1))
names = (self._extract_name(contact.o2), other_manager._extract_name(contact.o1))
reverse = True
if return_names:
@@ -445,11 +416,7 @@ class CollisionManager(object):
else:
return result
def min_distance_single(self,
mesh,
transform=None,
return_name=False,
return_data=False):
def min_distance_single(self, mesh, transform=None, return_name=False, return_data=False):
"""
Get the minimum distance between a single object and any
object in the manager.
@@ -486,10 +453,7 @@ class CollisionManager(object):
# Collide with manager's objects
ddata = fcl.DistanceData()
if return_data:
ddata = fcl.DistanceData(
fcl.DistanceRequest(enable_nearest_points=True),
fcl.DistanceResult()
)
ddata = fcl.DistanceData(fcl.DistanceRequest(enable_nearest_points=True), fcl.DistanceResult())
self._manager.distance(o, ddata, fcl.defaultDistanceCallback)
@@ -504,7 +468,7 @@ class CollisionManager(object):
name = self._extract_name(cg)
names = (name, '__external')
names = (name, "__external")
if cg == ddata.result.o2:
names = reversed(names)
data = DistanceData(names, ddata.result)
@@ -541,10 +505,7 @@ class CollisionManager(object):
"""
ddata = fcl.DistanceData()
if return_data:
ddata = fcl.DistanceData(
fcl.DistanceRequest(enable_nearest_points=True),
fcl.DistanceResult()
)
ddata = fcl.DistanceData(fcl.DistanceRequest(enable_nearest_points=True), fcl.DistanceResult())
self._manager.distance(ddata, fcl.defaultDistanceCallback)
@@ -552,8 +513,7 @@ class CollisionManager(object):
names, data = None, None
if return_names or return_data:
names = (self._extract_name(ddata.result.o1),
self._extract_name(ddata.result.o2))
names = (self._extract_name(ddata.result.o1), self._extract_name(ddata.result.o2))
data = DistanceData(names, ddata.result)
names = tuple(sorted(names))
@@ -566,8 +526,7 @@ class CollisionManager(object):
else:
return distance
def min_distance_other(self, other_manager,
return_names=False, return_data=False):
def min_distance_other(self, other_manager, return_names=False, return_data=False):
"""
Get the minimum distance between any pair of objects,
one in each manager.
@@ -596,26 +555,19 @@ class CollisionManager(object):
"""
ddata = fcl.DistanceData()
if return_data:
ddata = fcl.DistanceData(
fcl.DistanceRequest(enable_nearest_points=True),
fcl.DistanceResult()
)
ddata = fcl.DistanceData(fcl.DistanceRequest(enable_nearest_points=True), fcl.DistanceResult())
self._manager.distance(other_manager._manager,
ddata,
fcl.defaultDistanceCallback)
self._manager.distance(other_manager._manager, ddata, fcl.defaultDistanceCallback)
distance = ddata.result.min_distance
names, data = None, None
if return_names or return_data:
reverse = False
names = (self._extract_name(ddata.result.o1),
other_manager._extract_name(ddata.result.o2))
names = (self._extract_name(ddata.result.o1), other_manager._extract_name(ddata.result.o2))
if names[0] is None:
reverse = True
names = (self._extract_name(ddata.result.o2),
other_manager._extract_name(ddata.result.o1))
names = (self._extract_name(ddata.result.o2), other_manager._extract_name(ddata.result.o1))
dnames = tuple(names)
if reverse:
@@ -681,10 +633,8 @@ def mesh_to_BVH(mesh):
BVH of input geometry
"""
bvh = fcl.BVHModel()
bvh.beginModel(num_tris_=len(mesh.faces),
num_vertices_=len(mesh.vertices))
bvh.addSubModel(verts=mesh.vertices,
triangles=mesh.faces)
bvh.beginModel(num_tris_=len(mesh.faces), num_vertices_=len(mesh.vertices))
bvh.addSubModel(verts=mesh.vertices, triangles=mesh.faces)
bvh.endModel()
return bvh
@@ -709,7 +659,5 @@ def scene_to_collision(scene):
objects = {}
for node in scene.graph.nodes_geometry:
T, geometry = scene.graph[node]
objects[node] = manager.add_object(name=node,
mesh=scene.geometry[geometry],
transform=T)
objects[node] = manager.add_object(name=node, mesh=scene.geometry[geometry], transform=T)
return manager, objects