Skip to content
Snippets Groups Projects
Commit b976b13b authored by mehtank's avatar mehtank
Browse files

Face2face

parent 1036dd49
2 merge requests!34V0.4,!29Face2face
......@@ -221,10 +221,7 @@ class Face(object):
self.decorations.append(pts)
def addFace(self, face, transform, copyDecorations=False):
self.joinedFaces.append((face, transform))
if copyDecorations:
for d in self.decorations:
face.addDecoration(d)
self.joinedFaces.append(dict(face=face, transform=transform, copyDecorations=copyDecorations))
def preTransform(self, edge):
index = self.edges.index(edge)
......@@ -332,16 +329,38 @@ class Face(object):
e.remove(self)
# now place attached faces
for (f, t) in self.joinedFaces:
for jf in self.joinedFaces:
if jf["transform"] is False:
continue
if self.inverted:
t3d = np.dot(MirrorZ(), t)
t3d = np.dot(MirrorZ(), jf["transform"])
else:
t3d = t
t3d = jf["transform"]
t3d = np.dot(self.transform3D, t3d)
f.place(None, None, t3d, facelists)
jf["face"].place(None, None, t3d, facelists)
self.placeagain()
def copyDecorations(self):
for jf in self.joinedFaces:
if jf["copyDecorations"]:
thisdeco = self.transformDecorations(np.inv(jf["face"].transform3D))
thatdeco = jf["face"].transformDecorations(np.inv(self.transform3D))
self.decorations += thatdeco
jf["face"].decorations += thisdeco
jf["copyDecorations"] = False
def transformDecorations(self, t2=None):
if self.transform3D is None:
return
t = self.transform3D
if t2 is not None:
t = np.dot(t2, t)
decorations = []
for e in self.decorations:
decorations.append(([ np.dot(t, np.array(list(pt) + [0,1]))[0:2] for pt in e[0] ], e[1]))
return decorations
def polygon(self):
from collections import namedtuple
from shapely.geometry import Polygon
......
......@@ -122,9 +122,18 @@ class Graph():
toFace = self.getFace(toFaceName)
toFace.transform(origin=offset)
if transform is None:
transform = np.eye(4)
transform = np.eye(4)
invtransform = np.eye(4)
elif transform is False:
transform = False
invtransform = False
else:
invtransform = np.inv(transform)
fromFace.addFace(toFace, transform, copyDecorations)
toFace.addFace(fromFace, np.inv(transform), copyDecorations)
toFace.addFace(fromFace, invtransform, copyDecorations=False)
# XXX TODO have separate options for copyDecorations from->to vs to->from?
# Right now we'll do both during place, so only note it for one of the pair.
def attachEdge(self, fromEdge, newFace, newEdge, prefix=None, root=False, angle=0, edgeType=None, joints=None):
# XXX should set angle from a face, not absolute angle of the face
......@@ -300,11 +309,7 @@ class Graph():
import objgraph
objgraph.show_refs(self.graphObj(), max_depth = 2, filter = lambda x : isinstance(x, (dict, HyperEdge)))
def place(self, force=False, transform3D=None):
if force:
self.unplace()
self.facelists = []
def place(self, transform3D=None):
if transform3D is None:
transform3D = np.eye(4)
......@@ -318,16 +323,9 @@ class Graph():
else:
break
#IPython.embed()
self.rebuildEdges()
def unplace(self):
for f in self.faces:
f.transform2D = None
f.transform3D = None
for e in self.edges:
e.pts2D = None
e.pts3D = None
f.copyDecorations()
self.rebuildEdges()
def makeMeshes(self, **kwargs):
"""Create a list of stl Mesh objects"""
......
......@@ -41,4 +41,4 @@ class AnchorPort(FacePort):
if isinstance(fromPort, DecorationPort):
deco = fromPort.getDecoration().faces[0]
face = self.getFaceName()
self.graph.mergeFace(deco.joinedFaces[0][0].name, face, np.dot(self.getTransform(), deco.transform2D))
self.graph.mergeFace(deco.joinedFaces[0]["face"].name, face, np.dot(self.getTransform(), deco.transform2D))
from rocolib.api.ports import Port
from rocolib.utils.utils import prefix as prefixString
from rocolib.utils.numsym import deg2rad
from rocolib.utils.transforms import RotateX
from rocolib.utils.numsym import deg2rad, dot
from rocolib.utils.transforms import RotateX, RotateZ
class FacePort(Port):
def __init__(self, parent, graph, face):
......@@ -41,8 +41,11 @@ class FacePort(Port):
if isinstance(toPort, FacePort):
face1 = self.graph.getFace(self.getFaceName())
face2 = self.graph.getFace(toPort.getFaceName())
if kwargs.get("flip"):
transform = RotateX(deg2rad(180))
else:
transform = None
self.graph.mergeFace(face1.name, face2.name, transform=transform, offset=kwargs.get("offset", (0,0)), copyDecorations=True)
transform = kwargs.get("transform", None)
if transform is not False:
transform = dot(RotateX(deg2rad(kwargs.pop("flip", 0) and 180)), RotateZ(deg2rad(kwargs.pop("rotate", 0))))
self.graph.mergeFace(face1.name, face2.name, transform=transform,
offset=kwargs.pop("offset", (0,0)),
copyDecorations=kwargs.pop("copyDecorations", False))
......@@ -109,4 +109,11 @@ c.addConnection(("sheath", "face1"),
mode="hole",
offset=Function(*depthfn(["length", "battery"], "(4-(%s+x[3])/2, 0.5 * x[2] - 15)")))
c.addConnection(("right", "face0"),
("sheath", "face2"), copyDecorations=True, transform=False)
c.addConnection(("left", "face0"),
("sheath", "face0"), copyDecorations=True, transform=False)
c.addConnection(("brain", "face1"),
("sheath", "face1"), copyDecorations=True, transform=False)
c.toLibrary("ESPSeg")
......@@ -9,6 +9,6 @@ c.addSubcomponent("tire", "Tire", inherit="radius tire_thickness".split(), prefi
c.inheritAllInterfaces("drive", prefix=None)
c.addConnection(("drive", "horn"),
("tire", "face"))
("tire", "face"), copyDecorations=True)
c.toLibrary("Wheel")
from rocolib.api.components import Component
from rocolib.utils.utils import copyDecorations
class ESPSeg(Component):
def assemble(self):
copyDecorations(self, ("rightservoface", ("right", "face0", -1, 0)),
("rightservosheath", ("sheath", "face2", -1, 0)))
copyDecorations(self, ("leftservoface", ("left", "face0", 2, 1)),
("leftservosheath", ("sheath", "face0", 0, -1)))
copyDecorations(self, ("brainface", ("brain", "face1", 0, 1)),
("brainsheath", ("sheath", "face1", 1, 2)))
if __name__ == "__main__":
ESPSeg.test()
......@@ -11,6 +11,14 @@ connections:
- - left
- botedge0
- angle: -90
connection10:
- - brain
- face1
- &id001
- sheath
- face1
- copyDecorations: true
transform: false
connection2:
- - left
- topedge1
......@@ -48,8 +56,7 @@ connections:
- driveservo
- battery
connection7:
- - sheath
- face1
- *id001
- - usb
- decoration
- mode: hole
......@@ -61,6 +68,20 @@ connections:
- driveservo
- length
- battery
connection8:
- - right
- face0
- - sheath
- face2
- copyDecorations: true
transform: false
connection9:
- - left
- face0
- - sheath
- face0
- copyDecorations: true
transform: false
interfaces: {}
parameters:
battery:
......@@ -152,7 +173,7 @@ subcomponents:
center: false
length:
function: x[0] - getDim(x[1],'width')
parameter: &id001
parameter: &id002
- length
- controller
radius:
......@@ -172,7 +193,7 @@ subcomponents:
flip: true
length:
function: x[0] - getDim(x[1],'width')
parameter: *id001
parameter: *id002
radius:
parameter: height
servo:
......
......@@ -4,7 +4,7 @@ connections:
- horn
- - tire
- face
- {}
- copyDecorations: true
interfaces:
botedge0:
interface: botedge0
......
......@@ -45,30 +45,3 @@ def transformDecorations(face, pts2d, offset=(0,0), rotate=0, flip=False, mode=N
for p in pts2d], mode))
return np.dot(Translate([offset[0], offset[1], 0]), RotateZ(rotate))
def copyDecorations(self, deco_1, deco_2):
(ni1, (sc1, i1, p1a, p1b)) = deco_1
(ni2, (sc2, i2, p2a, p2b)) = deco_2
self.inheritInterface(ni1, (sc1, i1))
self.inheritInterface(ni2, (sc2, i2))
f1 = self.getInterface(ni1).getFace()
f2 = self.getInterface(ni2).getFace()
p1o = f1.pts2d[p1a]
p1x = f1.pts2d[p1b]
p2o = f2.pts2d[p2a]
p2x = f2.pts2d[p2b]
a1 = np.arctan2(p1x[1]-p1o[1], p1x[0]-p1o[0])
a2 = np.arctan2(p2x[1]-p2o[1], p2x[0]-p2o[0])
for pts, mode in f1.decorations:
transformDecorations(
f2,
[(px - p1o[0], py - p1o[1]) for (px, py) in pts],
offset = p2o,
rotate = np.rad2deg(a2-a1),
mode = mode
)
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment