Esempio n. 1
0
    def _build_polygon(self, radius, z, segments=32, reverse_vertex_order=False):
        """
        Generate a polygon given number of segments and radius

        :param radius:
        :param z:
        :param segments:
        :param reverse_vertex_order:
        :return:
        """
        vertex_start_index = len(self.vertices)

        for i in range(segments):
            angle = (math.pi / 2) + (i  / segments) * 2 * math.pi

            x = radius * math.cos(angle)
            y = radius * math.sin(angle)

            vertex = Vector3(x, y, z)
            self.vertices.append(vertex)

            if i >= 2:
                if reverse_vertex_order:
                    face = Face3(vertex_start_index + i,
                                 vertex_start_index + i-1,
                                 vertex_start_index)
                else:
                    face = Face3(vertex_start_index,
                                 vertex_start_index + i - 1,
                                 vertex_start_index + i)

                normal = self.calculate_normal(face)
                face.vertex_normals = [normal, normal, normal]
                self.faces.append(face)
Esempio n. 2
0
    def _build_cylinder(self):
        """
        Generate faces between top and bottom faces
        :return:
        """
        top_circle_vertex_start_index = len(self.vertices) // 2

        for i in range(top_circle_vertex_start_index):
            base_v0 = i
            base_v1 = i + 1
            top_v0 = i + top_circle_vertex_start_index
            top_v1 = top_v0 + 1
            if base_v1 == top_circle_vertex_start_index:
                base_v1 = 0
                top_v1 = top_circle_vertex_start_index

            # two points on first circle, one on second circle
            face = Face3(base_v0, base_v1, top_v0)
            normal = self.calculate_normal(face)
            face.vertex_normals = [normal, normal, normal]
            self.faces.append(face)

            # one point on first circle, two on second circle
            face = Face3(base_v1, top_v1, top_v0)
            normal = self.calculate_normal(face)
            face.vertex_normals = [normal, normal, normal]
            self.faces.append(face)
Esempio n. 3
0
    def build_sphere(self, radius, sectors, stacks):

        for i in range(stacks):
            stack_angle = math.pi * ((1 / 2) - (i / stacks))
            xy = radius * math.cos(stack_angle)
            z = radius * math.sin(stack_angle)

            # add(sectorCount + 1) vertices per stack
            # the first and last vertices have same position and normal, but different tex coords
            for j in range(sectors):
                sector_angle = j * 2 * math.pi / sectors

                # vertex position x y z
                x = xy * math.cos(sector_angle)
                y = xy * math.sin(sector_angle)
                vec = Vector3(x, y, z)
                self.vertices.append(vec)

                # normals
                # length_inv = 1 / radius
                # nx = x * length_inv
                # ny = y * length_inv
                # nz = z * length_inv
                # normal = Vector3(nx, ny, nz)
                # self.normals.append(normal)

                # tex coords (s, t) range between [0, 1]
                # TODO: https://www.songho.ca/opengl/gl_sphere.html

        for i in range(stacks):
            k_1 = i * (sectors)  # beginning of current stack
            k_2 = k_1 + sectors  # beginning of next stack

            for j in range(sectors):
                # faces
                #
                # if i = 0:
                #     face = Face3(0, k_2)
                #
                if i != 0:
                    face = Face3(k_1, k_2, k_1 + 1)
                    # normal = self.calculate_normal(face)
                    # face.vertex_normals = [normal, normal, normal]
                    self.faces.append(face)

                if i != (stacks - 1):
                    face = Face3(k_1 + 1, k_2, k_2 + 1)
                    # normal = self.calculate_normal(face)
                    # face.vertex_normals = [normal, normal, normal]
                    self.faces.append(face)

                k_1 += 1
                k_2 += 1

        for face in self.faces:
            if face.a > len(self.vertices) \
                    or face.b > len(self.vertices) \
                    or face.c > len(self.vertices):
                print(face)
Esempio n. 4
0
    def create_mesh(self):
        """ Create real mesh object from the geometry and material """
        max_faces = 65530//3
        #geometries = []
        start = 0

        while(True):
            _faces=[]
            _vertices = []
            if (len(self.stl_mesh.v0)-start) >= max_faces:
                print("Faces are more than max")
                length = max_faces
                #
                # mesh = STLMesh(self.stl_mesh.v0[start:start+length], self.stl_mesh.v1[start:start+length], self.stl_mesh.v2[start:start+length], self.stl_mesh.normals[start:start+length],
                # self.material)
                #
                # self.add(mesh)
                _vertices = np.concatenate((self.stl_mesh.v0[start:start+length],self.stl_mesh.v1[start:start+length],self.stl_mesh.v2[start:start+length]))
                for i in range(length):

                    f3 = Face3(i,i+length, i+ length*2)
                    f3.vertex_normals = [self.stl_mesh.normals[start+i],self.stl_mesh.normals[start+i],self.stl_mesh.normals[start+i]]
                    _faces.append(f3)



                geo = Geometry()
                geo.vertices = _vertices
                geo.faces = _faces
                mesh = Mesh(geo, self.material)
                self.add(mesh)
                start = start+length


            else:
                length = len(self.stl_mesh.v0)-start
                _vertices = np.concatenate((self.stl_mesh.v0[start:],self.stl_mesh.v1[start:],self.stl_mesh.v2[start:]))
                for i in range(length):
                    f3 = Face3(i,i+length, i+ length*2)
                    f3.vertex_normals = [self.stl_mesh.normals[i+start],self.stl_mesh.normals[i+start],self.stl_mesh.normals[i+start]]
                    _faces.append(f3)
                geo = Geometry()
                geo.vertices = _vertices
                geo.faces = _faces
                #geometries.append(geo)
                mesh = Mesh(geo, self.material)
                self.add(mesh)

                # length = max_faces
                #
                # mesh = STLMesh(self.stl_mesh.v0[start:], self.stl_mesh.v1[start:], self.stl_mesh.v2[start:], self.stl_mesh.normals[start:],
                # self.material)
                #
                # self.add(mesh)
                break

        return self
Esempio n. 5
0
 def _build_msh(self):
     for v in self.msh_vertices:
         v0 = Vector3(v[0] * 0.4, v[1] * 0.4, v[2] * 0.4)
         self.vertices.append((v0[0], v0[1], v0[2]))
     print len(self.vertices)
     n_idx = 0
     for f in self.msh_faces:
         face3 = Face3(*f)
         normal = self.msh_normals[n_idx]
         #face3.vertex_normals = [normal, normal, normal]
         face3.normal = normal
         n_idx += 1
         self.faces.append(face3)
Esempio n. 6
0
    def _build_box(self):

        for v in self._cube_vertices:
            v = Vector3(0.5 * v[0] * self.w, 0.5 * v[1] * self.h,
                        0.5 * v[2] * self.d)
            self.vertices.append(v)

        n_idx = 0
        for f in self._cube_faces:
            face3 = Face3(*f)
            normal = self._cube_normals[floor(n_idx / 2)]
            face3.vertex_normals = [normal, normal, normal]
            n_idx += 1
            self.faces.append(face3)
Esempio n. 7
0
    def _build_tri(self):

        for v in self._tri_vertices:
            v = Vector3(0.5 * v[0] * self.w, 0.5 * v[1] * self.h,
                        0.5 * v[2] * self.d)
            self.vertices.append(v)

        n_idx = 0
        for f in self._tri_faces:
            face3 = Face3(*f)
            normal = self._tri_normals[n_idx / 2]
            face3.vertex_normals = [normal, normal, normal]
            n_idx += 1
            self.faces.append(face3)
Esempio n. 8
0
    def _build_mesh(self, stl_mesh):

        for i in range(stl_mesh.attr.size):
            for j in range(3):
                v = Vector3(stl_mesh.vectors[i][j][0],
                            stl_mesh.vectors[i][j][1],
                            stl_mesh.vectors[i][j][2])
                self.vertices.append(v)

            f_index = i * 3
            face3 = Face3(f_index, f_index + 1, f_index + 2)
            face3.normal = Vector3(stl_mesh.normals[i][0],
                                   stl_mesh.normals[i][1],
                                   stl_mesh.normals[i][2])
            face3.vertex_normals = [face3.normal, face3.normal, face3.normal]
            self.faces.append(face3)
Esempio n. 9
0
    def convert_to_mesh(self, vertex_format=None):
        """Converts data gotten from the .obj definition
        file and create Kivy3 Mesh object which may be used
        for drawing object in the scene
        """

        geometry = Geometry()
        material = Material()
        mtl_dirname = os.path.abspath(os.path.dirname(self.loader.mtl_source))

        v_idx = 0
        # create geometry for mesh
        for f in self.faces:
            verts = f[0]
            norms = f[1]
            tcs = f[2]
            face3 = Face3(0, 0, 0)
            for i, e in enumerate(['a', 'b', 'c']):
                #get normal components
                n = (0.0, 0.0, 0.0)
                if norms[i] != -1:
                    n = self.loader.normals[norms[i] - 1]
                face3.vertex_normals.append(n)

                #get vertex components
                v = self.loader.vertices[verts[i] - 1]
                geometry.vertices.append(v)
                setattr(face3, e, v_idx)
                v_idx += 1

                #get texture coordinate components
                t = (0.0, 0.0)
                if tcs[i] != -1:
                    t = self.loader.texcoords[tcs[i] - 1]
                tc = Vector2(t[0], 1. - t[1])
                geometry.face_vertex_uvs[0].append(tc)

            geometry.faces.append(face3)

        # apply material for object
        if self.mtl_name in self.loader.mtl_contents:
            raw_material = self.loader.mtl_contents[self.mtl_name]
            for k, v in raw_material.iteritems():
                _k = self._mtl_map.get(k, None)
                if k in [
                        "map_Kd",
                ]:
                    map_path = os.path.join(mtl_dirname, v[0])
                    tex = Image(map_path).texture
                    material.map = tex
                    continue
                if _k:
                    if len(v) == 1:
                        v = float(v[0])
                        if k == 'Tr':
                            v = 1. - v
                        setattr(material, _k, v)
                    else:
                        v = map(lambda x: float(x), v)
                        setattr(material, _k, v)
        mesh = Mesh(geometry, material)
        return mesh
Esempio n. 10
0
    def _build_cylinder(self):

        _cylinder_vertices = []
        top_vertices = []
        bottom_vertices = []
        cylinder_side_normals = []
        _cylinder_normals = []

        for i in range(self.circle_segment):
            x = math.cos(
                float(i) * (2. * math.pi) /
                float(self.circle_segment)) * 0.5 * float(self.rad)
            y = math.sin(
                float(i) * (2. * math.pi) /
                float(self.circle_segment)) * 0.5 * float(self.rad)

            n = Vector3(x, y, 0)
            n.normalize()
            cylinder_side_normals.append(n)

            top_vertices.append((x, y, 0.5 * float(self.length)))
            bottom_vertices.append((x, y, -0.5 * float(self.length)))

        _cylinder_vertices = top_vertices + bottom_vertices
        _cylinder_normals = cylinder_side_normals + cylinder_side_normals

        for f in range(1, self.circle_segment - 1):
            # Top circle
            normal = Vector3(0, 0, 1)
            face = (0, f, f + 1)
            face3 = Face3(*face)
            face3.vertex_normals = [normal, normal, normal]
            self.faces.append(face3)

        for f in range(self.circle_segment + 1, (2 * self.circle_segment) - 1):
            # Top circle
            normal = Vector3(0, 0, -1)
            face = (self.circle_segment, f, f + 1)
            face3 = Face3(*face)
            face3.vertex_normals = [normal, normal, normal]
            self.faces.append(face3)

        for i in range(0, self.circle_segment):
            if i == (self.circle_segment - 1):
                face = (i, 0, i + self.circle_segment)
            else:
                face = (i, i + 1, i + self.circle_segment)
            face3 = Face3(*face)
            face3.vertex_normals = [
                _cylinder_normals[i], _cylinder_normals[i + 1],
                _cylinder_normals[i + self.circle_segment]
            ]
            self.faces.append(face3)

            if i == (self.circle_segment - 1):
                face = (0, i + self.circle_segment, self.circle_segment)
                face3 = Face3(*face)
                face3.vertex_normals = (_cylinder_normals[i + 1],
                                        _cylinder_normals[i +
                                                          self.circle_segment],
                                        _cylinder_normals[self.circle_segment])
            else:
                face = (i + 1, i + self.circle_segment,
                        i + self.circle_segment + 1)

                face3 = Face3(*face)
                face3.vertex_normals = (_cylinder_normals[i + 1],
                                        _cylinder_normals[i +
                                                          self.circle_segment],
                                        _cylinder_normals[i +
                                                          self.circle_segment +
                                                          1])
            self.faces.append(face3)

        self.vertices = _cylinder_vertices
Esempio n. 11
0
    def _build_sphere(self):
        #Create Vertices and normals
        _vertices = []
        _normals = []
        #Top vertex
        _vertices.append((0, 0, 1. * self.rad))
        _normals.append((0, 0, 1))

        # Generate the faces
        for i in range(1, self.stacks):
            theta_1 = float(i) * (math.pi / self.stacks)
            z = math.cos(theta_1)
            for j in range(self.sectors):
                theta_2 = float(j) * (2. * math.pi / self.sectors)
                x = math.sin(theta_1) * math.cos(theta_2)
                y = math.sin(theta_1) * math.sin(theta_2)

                vertex = (x * self.rad, y * self.rad, z * self.rad)
                _vertices.append(vertex)
                _normals.append((x, y, z))

        # Bottom vertex
        _vertices.append((0, 0, -1. * self.rad))
        _normals.append((0, 0, -1.))

        # Generate the Faces with mapping to the vertices

        #Top one
        for i in range(1, self.sectors + 1):

            a = 0
            b = i
            c = i + 1
            if c == self.sectors + 1:
                c = 1
            face3 = Face3(a, b, c)
            face3.vertex_normals = [_normals[a], _normals[b], _normals[c]]
            self.faces.append(face3)

        #Stacks:
        for i in range(0, self.stacks - 2):
            top_idx = (i * self.sectors + 1, (i + 1) * self.sectors + 1)
            for j in range(top_idx[0], top_idx[1]):
                a = j
                b = j + 1
                c = j + self.sectors
                if b == top_idx[1]:
                    b = top_idx[0]
                face3 = Face3(a, b, c)
                face3.vertex_normals = [_normals[a], _normals[b], _normals[c]]
                self.faces.append(face3)

                a = j + 1
                b = j + self.sectors
                c = j + self.sectors + 1
                if a == top_idx[1]:
                    a = top_idx[0]
                if c == top_idx[1] + self.sectors:
                    c = top_idx[1]

                face3 = Face3(a, b, c)
                face3.vertex_normals = [_normals[a], _normals[b], _normals[c]]
                self.faces.append(face3)

        for i in range(len(_vertices) - 1 - self.sectors, len(_vertices) - 1):

            a = len(_vertices) - 1
            b = i
            c = i + 1
            if c == len(_vertices) - 1:
                c = len(_vertices) - 1 - self.sectors
            face3 = Face3(a, b, c)
            face3.vertex_normals = [_normals[a], _normals[b], _normals[c]]
            self.faces.append(face3)

        self.vertices = _vertices
Esempio n. 12
0
    def convert_to_mesh(self, vertex_format=None):
        """Converts data gotten from the .obj definition
        file and create Kivy3 Mesh object which may be used
        for drawing object in the scene
        """

        geometry = Geometry()
        material = Material()
        mtl_dirname = abspath(dirname(self.loader.mtl_source))

        v_idx = 0
        # create geometry for mesh
        for f in self.faces:
            verts = f[0]
            norms = f[1]
            tcs = f[2]
            face3 = Face3(0, 0, 0)
            for i, e in enumerate(['a', 'b', 'c']):
                # get normal components
                n = (0.0, 0.0, 0.0)
                if norms[i] != -1:
                    n = self.loader.normals[norms[i] - 1]
                face3.vertex_normals.append(n)

                # get vertex components
                v = self.loader.vertices[verts[i] - 1]
                geometry.vertices.append(v)
                setattr(face3, e, v_idx)
                v_idx += 1

                # get texture coordinate components
                t = (0.0, 0.0)
                if tcs[i] != -1:
                    t = self.loader.texcoords[tcs[i] - 1]
                tc = Vector2(t[0], 1. - t[1])
                geometry.face_vertex_uvs[0].append(tc)

            geometry.faces.append(face3)

        # apply material for object
        if self.mtl_name in self.loader.mtl_contents:
            raw_material = self.loader.mtl_contents[self.mtl_name]
            # shader ignores values
            zeros = ['0', '0.0', '0.00', '0.000', '0.0000',
                     '0.00000', '0.000000']
            for k, v in raw_material.items():
                _k = self._mtl_map.get(k, None)
                # TODO: also handle map_Ka and map_Ks
                if k in ["map_Kd", ]:
                    # TODO: map file path may contains spaces.
                    #      current implementation fails.
                    map_path = join(mtl_dirname, v[0])
                    if not exists(map_path):
                        msg = u'WaveObject: Texture not found <{}>'
                        Logger.warning(msg.format(map_path))
                        continue
                    tex = Image(map_path).texture
                    material.map = tex
                    continue
                if _k:
                    if len(v) == 1:
                        v[0] = '0.000001' if v[0] in zeros else v[0]
                        v = float(v[0])
                        if k == 'Tr':
                            v = 1. - v
                        setattr(material, _k, v)
                    else:
                        v = list(map(lambda x: float(x), v))
                        setattr(material, _k, v)

        if not material.map:
            material.map = Image(folder + '/empty.png').texture
            material.texture_ratio = 0.0
        mesh = Mesh(geometry, material)
        return mesh