Skip to content

Added .pyi files #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pywavefront/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from _typeshed import Incomplete
from pywavefront.exceptions import PywavefrontException as PywavefrontException
from pywavefront.obj import ObjParser as ObjParser
from pywavefront.wavefront import Wavefront as Wavefront

__version__: str
logger: Incomplete
log_handler: Incomplete

def configure_logging(level, formatter: Incomplete | None = None) -> None: ...
59 changes: 59 additions & 0 deletions pywavefront/cache.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from _typeshed import Incomplete
from pywavefront.material import MaterialParser

logger: Incomplete

def cache_name(path):
"""Generate the name of the binary cache file"""
def meta_name(path):
"""Generate the name of the meta file"""

class CacheLoader:
material_parser_cls = MaterialParser
wavefront: Incomplete
file_name: Incomplete
path: Incomplete
encoding: Incomplete
strict: Incomplete
dir: Incomplete
meta: Incomplete
def __init__(self, file_name, wavefront, strict: bool = False, create_materials: bool = False, encoding: str = 'utf-8', parse: bool = True, **kwargs) -> None: ...
def parse(self): ...
def load_vertex_buffer(self, fd, material, length) -> None:
"""
Load vertex data from file. Can be overriden to reduce data copy

:param fd: file object
:param material: The material these vertices belong to
:param length: Byte length of the vertex data
"""

class CacheWriter:
file_name: Incomplete
wavefront: Incomplete
meta: Incomplete
def __init__(self, file_name, wavefront) -> None: ...
def write(self) -> None: ...

class Meta:
"""
Metadata for binary obj cache files
"""
format_version: str
def __init__(self, **kwargs) -> None: ...
def add_vertex_buffer(self, material, vertex_format, byte_offset, byte_length) -> None:
"""Add a vertex buffer"""
@classmethod
def from_file(cls, path): ...
def write(self, path) -> None:
"""Save the metadata as json"""
@property
def version(self): ...
@property
def created_at(self): ...
@property
def vertex_buffers(self): ...
@property
def mtllibs(self): ...
@mtllibs.setter
def mtllibs(self, value) -> None: ...
2 changes: 2 additions & 0 deletions pywavefront/exceptions.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class PywavefrontException(Exception):
"""Generic exception for this package to separate from common ones"""
102 changes: 102 additions & 0 deletions pywavefront/material.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from _typeshed import Incomplete
from pathlib import Path as Path
from pywavefront.parser import Parser
from pywavefront.texture import Texture

logger: Incomplete

class Material:
texture_cls = Texture
name: Incomplete
diffuse: Incomplete
ambient: Incomplete
specular: Incomplete
emissive: Incomplete
transparency: float
shininess: float
optical_density: float
illumination_model: int
texture: Incomplete
texture_ambient: Incomplete
texture_specular_color: Incomplete
texture_specular_highlight: Incomplete
texture_alpha: Incomplete
texture_bump: Incomplete
is_default: Incomplete
vertex_format: str
vertices: Incomplete
gl_floats: Incomplete
def __init__(self, name, is_default: bool = False, has_faces: bool = False) -> None:
"""
Create a new material
:param name: Name of the material
:param is_default: Is this an auto created default material?
"""
@property
def has_normals(self): ...
@property
def has_uvs(self): ...
@property
def has_colors(self): ...
@property
def vertex_size(self):
"""How many float each vertex contains in the interleaved data"""
def pad_light(self, values):
"""Accept an array of up to 4 values, and return an array of 4 values.
If the input array is less than length 4, pad it with zeroes until it
is length 4. Also ensure each value is a float"""
def set_alpha(self, alpha) -> None:
"""Set alpha/last value on all four lighting attributes."""
def set_diffuse(self, values: Incomplete | None = None) -> None: ...
def set_ambient(self, values: Incomplete | None = None) -> None: ...
def set_specular(self, values: Incomplete | None = None) -> None: ...
def set_emissive(self, values: Incomplete | None = None) -> None: ...
def set_texture(self, name, search_path) -> None: ...
def set_texture_ambient(self, name, search_path) -> None: ...
def set_texture_specular_color(self, name, search_path) -> None: ...
def set_texture_specular_highlight(self, name, search_path) -> None: ...
def set_texture_alpha(self, name, search_path) -> None: ...
def set_texture_bump(self, name, search_path) -> None: ...
def unset_texture(self) -> None: ...

class MaterialParser(Parser):
"""Object to parse lines of a materials definition file."""
materials: Incomplete
this_material: Incomplete
collect_faces: Incomplete
def __init__(self, file_name, strict: bool = False, encoding: str = 'utf-8', parse: bool = True, collect_faces: bool = False) -> None:
"""
Create a new material parser
:param file_name: file name and path of obj file to read
:param strict: Enable strict mode
:param encoding: Encoding to read the text files
:param parse: Should parse be called immediately or manually called later?
"""
def parse_newmtl(self) -> None: ...
def parse_Kd(self) -> None: ...
def parse_Ka(self) -> None: ...
def parse_Ks(self) -> None: ...
def parse_Ke(self) -> None: ...
def parse_Ns(self) -> None: ...
def parse_d(self) -> None:
"""Transparency"""
def parse_Tr(self) -> None:
"""Transparency (alternative)"""
def parse_map_Kd(self) -> None:
"""Diffuse map"""
def parse_map_Ka(self) -> None:
"""Ambient map"""
def parse_map_Ks(self) -> None:
"""Specular color map"""
def parse_map_Ns(self) -> None:
"""Specular color map"""
def parse_map_d(self) -> None:
"""Alpha map"""
def parse_bump(self) -> None:
"""Bump map (from the spec)"""
def parse_map_bump(self) -> None:
"""Bump map (variant)"""
def parse_map_Bump(self) -> None:
"""Bump map (variant)"""
def parse_Ni(self) -> None: ...
def parse_illum(self) -> None: ...
14 changes: 14 additions & 0 deletions pywavefront/mesh.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from _typeshed import Incomplete

class Mesh:
"""This is a basic mesh for drawing using OpenGL. Interestingly, it does
not contain its own vertices. These are instead drawn via materials."""
name: Incomplete
materials: Incomplete
has_faces: Incomplete
faces: Incomplete
def __init__(self, name: Incomplete | None = None, has_faces: bool = False) -> None: ...
def has_material(self, new_material):
"""Determine whether we already have a material of this name."""
def add_material(self, material) -> None:
"""Add a material to the mesh, IF it's not already present."""
84 changes: 84 additions & 0 deletions pywavefront/obj.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from _typeshed import Incomplete
from collections.abc import Generator
from pywavefront.cache import CacheLoader, CacheWriter, Meta as Meta
from pywavefront.material import MaterialParser
from pywavefront.parser import Parser

logger: Incomplete

class ObjParser(Parser):
"""This parser parses lines from .obj files."""
material_parser_cls = MaterialParser
cache_loader_cls = CacheLoader
cache_writer_cls = CacheWriter
wavefront: Incomplete
mesh: Incomplete
material: Incomplete
create_materials: Incomplete
collect_faces: Incomplete
cache: Incomplete
cache_loaded: Incomplete
normals: Incomplete
tex_coords: Incomplete
def __init__(self, wavefront, file_name, strict: bool = False, encoding: str = 'utf-8', create_materials: bool = False, collect_faces: bool = False, parse: bool = True, cache: bool = False) -> None:
"""
Create a new obj parser
:param wavefront: The wavefront object
:param file_name: file name and path of obj file to read
:param strict: Enable strict mode
:param encoding: Encoding to read the text files
:param create_materials: Create materials if they don't exist
:param cache: Cache the loaded obj files in binary format
:param parse: Should parse be called immediately or manually called later?
"""
def parse(self) -> None:
"""Trigger cache load or call superclass parse()"""
def load_cache(self) -> None:
"""Loads the file using cached data"""
def post_parse(self) -> None:
"""Called after parsing is done"""
def parse_v(self) -> None: ...
line: Incomplete
values: Incomplete
def consume_vertices(self) -> Generator[Incomplete]:
"""
Consumes all consecutive vertices.
NOTE: There is no guarantee this will consume all vertices since other
statements can also occur in the vertex list
"""
def parse_vn(self) -> None: ...
def consume_normals(self) -> Generator[Incomplete]:
"""Consumes all consecutive texture coordinate lines"""
def parse_vt(self) -> None: ...
def consume_texture_coordinates(self) -> Generator[Incomplete]:
"""Consume all consecutive texture coordinates"""
def parse_mtllib(self) -> None: ...
def parse_usemtl(self) -> None: ...
def parse_usemat(self) -> None: ...
def parse_o(self) -> None: ...
def parse_f(self) -> None: ...
def consume_faces(self, collected_faces: Incomplete | None = None) -> Generator[Incomplete, Incomplete]:
"""
Consume all consecutive faces

If more than three vertices are specified, we triangulate by the following procedure:

Let the face have n vertices in the order v_1 v_2 v_3 ... v_n, n >= 3.
We emit the first face as usual: (v_1, v_2, v_3). For each remaining vertex v_j,
j > 3, we emit (v_j, v_1, v_{j - 1}), e.g. (v_4, v_1, v_3), (v_5, v_1, v_4).

In a perfect world we could consume all vertices straight forward and draw using
GL_TRIANGLE_FAN (which exactly matches the procedure above).
This is however rarely the case.

* If the face is co-planar but concave, then you need to triangulate the face.
* If the face is not-coplanar, you are screwed, because OBJ doesn't preserve enough information
to know what tessellation was intended.

We always triangulate to make it simple.

:param collected_faces: A list into which all (possibly triangulated) faces will be written in the form
of triples of the corresponding absolute vertex IDs. These IDs index the list
self.wavefront.vertices.
Specify None to prevent consuming faces (and thus saving memory usage).
"""
47 changes: 47 additions & 0 deletions pywavefront/parser.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from _typeshed import Incomplete
from collections.abc import Generator

logger: Incomplete

def auto_consume(func):
"""Decorator for auto consuming lines when leaving the function"""

class Parser:
"""This defines a generalized parse dispatcher; all parse functions
reside in subclasses."""
auto_post_parse: bool
file_name: Incomplete
strict: Incomplete
encoding: Incomplete
dir: Incomplete
dispatcher: Incomplete
lines: Incomplete
line: Incomplete
values: Incomplete
def __init__(self, file_name, strict: bool = False, encoding: str = 'utf-8') -> None:
"""
Initializer for the base parser
:param file_name: Name and path of the file to read
:param strict: Enable or disable strict mode
"""
def create_line_generator(self) -> Generator[Incomplete]:
"""
Creates a generator function yielding lines in the file
Should only yield non-empty lines
"""
def next_line(self) -> None:
"""Read the next line from the line generator and split it"""
def consume_line(self) -> None:
"""
Tell the parser we are done with this line.
This is simply by setting None values.
"""
def parse(self) -> None:
"""
Parse all the lines in the obj file
Determines what type of line we are and dispatch appropriately.
"""
def post_parse(self) -> None:
"""Override to trigger operations after parsing is complete"""
def parse_fallback(self) -> None:
"""Fallback method when parser doesn't know the statement"""
Loading