mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2026-02-26 08:06:00 +08:00
Compare commits
16 Commits
v0.7.9
...
3ba2030aa4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ba2030aa4 | ||
|
|
79a7fcf02b | ||
|
|
e43ed8c76e | ||
|
|
49f43402c6 | ||
|
|
90646d93ab | ||
|
|
eabb511410 | ||
|
|
e70188ebbc | ||
|
|
1bd911d534 | ||
|
|
3aadd19a2b | ||
|
|
42d66c1145 | ||
|
|
e9ed1cb178 | ||
|
|
cbcae096a0 | ||
|
|
5b1cce56bc | ||
|
|
0c3b204375 | ||
|
|
6be5e2da06 | ||
|
|
f5f6b78e70 |
@@ -19,7 +19,6 @@
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
import unittest.mock as mock
|
||||
|
||||
from recommonmark.parser import CommonMarkParser
|
||||
|
||||
@@ -48,22 +48,18 @@ The outputs of the experiment are saved and logged in multiple ways:
|
||||
import logging
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from dataclasses import field
|
||||
|
||||
import hydra
|
||||
|
||||
import torch
|
||||
from accelerate import Accelerator
|
||||
from omegaconf import DictConfig, OmegaConf
|
||||
from packaging import version
|
||||
|
||||
from pytorch3d.implicitron.dataset.data_source import (
|
||||
DataSourceBase,
|
||||
ImplicitronDataSource,
|
||||
)
|
||||
from pytorch3d.implicitron.models.base_model import ImplicitronModelBase
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.multipass_ea import (
|
||||
MultiPassEmissionAbsorptionRenderer,
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ import os
|
||||
from typing import Optional
|
||||
|
||||
import torch.optim
|
||||
|
||||
from accelerate import Accelerator
|
||||
from pytorch3d.implicitron.models.base_model import ImplicitronModelBase
|
||||
from pytorch3d.implicitron.tools import model_io
|
||||
|
||||
@@ -14,9 +14,7 @@ from dataclasses import field
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import torch.optim
|
||||
|
||||
from accelerate import Accelerator
|
||||
|
||||
from pytorch3d.implicitron.models.base_model import ImplicitronModelBase
|
||||
from pytorch3d.implicitron.tools import model_io
|
||||
from pytorch3d.implicitron.tools.config import (
|
||||
|
||||
@@ -12,7 +12,6 @@ import unittest
|
||||
from pathlib import Path
|
||||
|
||||
import torch
|
||||
|
||||
from hydra import compose, initialize_config_dir
|
||||
from omegaconf import OmegaConf
|
||||
from projects.implicitron_trainer.impl.optimizer_factory import (
|
||||
|
||||
@@ -18,68 +18,89 @@ namespace Renderer {
|
||||
|
||||
template <bool DEV>
|
||||
HOST void destruct(Renderer* self) {
|
||||
if (self->result_d != NULL)
|
||||
if (self->result_d != NULL) {
|
||||
FREE(self->result_d);
|
||||
}
|
||||
self->result_d = NULL;
|
||||
if (self->min_depth_d != NULL)
|
||||
if (self->min_depth_d != NULL) {
|
||||
FREE(self->min_depth_d);
|
||||
}
|
||||
self->min_depth_d = NULL;
|
||||
if (self->min_depth_sorted_d != NULL)
|
||||
if (self->min_depth_sorted_d != NULL) {
|
||||
FREE(self->min_depth_sorted_d);
|
||||
}
|
||||
self->min_depth_sorted_d = NULL;
|
||||
if (self->ii_d != NULL)
|
||||
if (self->ii_d != NULL) {
|
||||
FREE(self->ii_d);
|
||||
}
|
||||
self->ii_d = NULL;
|
||||
if (self->ii_sorted_d != NULL)
|
||||
if (self->ii_sorted_d != NULL) {
|
||||
FREE(self->ii_sorted_d);
|
||||
}
|
||||
self->ii_sorted_d = NULL;
|
||||
if (self->ids_d != NULL)
|
||||
if (self->ids_d != NULL) {
|
||||
FREE(self->ids_d);
|
||||
}
|
||||
self->ids_d = NULL;
|
||||
if (self->ids_sorted_d != NULL)
|
||||
if (self->ids_sorted_d != NULL) {
|
||||
FREE(self->ids_sorted_d);
|
||||
}
|
||||
self->ids_sorted_d = NULL;
|
||||
if (self->workspace_d != NULL)
|
||||
if (self->workspace_d != NULL) {
|
||||
FREE(self->workspace_d);
|
||||
}
|
||||
self->workspace_d = NULL;
|
||||
if (self->di_d != NULL)
|
||||
if (self->di_d != NULL) {
|
||||
FREE(self->di_d);
|
||||
}
|
||||
self->di_d = NULL;
|
||||
if (self->di_sorted_d != NULL)
|
||||
if (self->di_sorted_d != NULL) {
|
||||
FREE(self->di_sorted_d);
|
||||
}
|
||||
self->di_sorted_d = NULL;
|
||||
if (self->region_flags_d != NULL)
|
||||
if (self->region_flags_d != NULL) {
|
||||
FREE(self->region_flags_d);
|
||||
}
|
||||
self->region_flags_d = NULL;
|
||||
if (self->num_selected_d != NULL)
|
||||
if (self->num_selected_d != NULL) {
|
||||
FREE(self->num_selected_d);
|
||||
}
|
||||
self->num_selected_d = NULL;
|
||||
if (self->forw_info_d != NULL)
|
||||
if (self->forw_info_d != NULL) {
|
||||
FREE(self->forw_info_d);
|
||||
}
|
||||
self->forw_info_d = NULL;
|
||||
if (self->min_max_pixels_d != NULL)
|
||||
if (self->min_max_pixels_d != NULL) {
|
||||
FREE(self->min_max_pixels_d);
|
||||
}
|
||||
self->min_max_pixels_d = NULL;
|
||||
if (self->grad_pos_d != NULL)
|
||||
if (self->grad_pos_d != NULL) {
|
||||
FREE(self->grad_pos_d);
|
||||
}
|
||||
self->grad_pos_d = NULL;
|
||||
if (self->grad_col_d != NULL)
|
||||
if (self->grad_col_d != NULL) {
|
||||
FREE(self->grad_col_d);
|
||||
}
|
||||
self->grad_col_d = NULL;
|
||||
if (self->grad_rad_d != NULL)
|
||||
if (self->grad_rad_d != NULL) {
|
||||
FREE(self->grad_rad_d);
|
||||
}
|
||||
self->grad_rad_d = NULL;
|
||||
if (self->grad_cam_d != NULL)
|
||||
if (self->grad_cam_d != NULL) {
|
||||
FREE(self->grad_cam_d);
|
||||
}
|
||||
self->grad_cam_d = NULL;
|
||||
if (self->grad_cam_buf_d != NULL)
|
||||
if (self->grad_cam_buf_d != NULL) {
|
||||
FREE(self->grad_cam_buf_d);
|
||||
}
|
||||
self->grad_cam_buf_d = NULL;
|
||||
if (self->grad_opy_d != NULL)
|
||||
if (self->grad_opy_d != NULL) {
|
||||
FREE(self->grad_opy_d);
|
||||
}
|
||||
self->grad_opy_d = NULL;
|
||||
if (self->n_grad_contributions_d != NULL)
|
||||
if (self->n_grad_contributions_d != NULL) {
|
||||
FREE(self->n_grad_contributions_d);
|
||||
}
|
||||
self->n_grad_contributions_d = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,9 @@ GLOBAL void norm_sphere_gradients(Renderer renderer, const int num_balls) {
|
||||
// The sphere only contributes to the camera gradients if it is
|
||||
// large enough in screen space.
|
||||
if (renderer.ids_sorted_d[idx] > 0 && ii.max.x >= ii.min.x + 3 &&
|
||||
ii.max.y >= ii.min.y + 3)
|
||||
ii.max.y >= ii.min.y + 3) {
|
||||
renderer.ids_sorted_d[idx] = 1;
|
||||
}
|
||||
END_PARALLEL_NORET();
|
||||
};
|
||||
|
||||
|
||||
@@ -139,8 +139,9 @@ GLOBAL void render(
|
||||
coord_y < cam_norm.film_border_top + cam_norm.film_height) {
|
||||
// Initialize the result.
|
||||
if (mode == 0u) {
|
||||
for (uint c_id = 0; c_id < cam_norm.n_channels; ++c_id)
|
||||
for (uint c_id = 0; c_id < cam_norm.n_channels; ++c_id) {
|
||||
result[c_id] = bg_col[c_id];
|
||||
}
|
||||
} else {
|
||||
result[0] = 0.f;
|
||||
}
|
||||
@@ -190,20 +191,22 @@ GLOBAL void render(
|
||||
"render|found intersection with sphere %u.\n",
|
||||
sphere_id_l[write_idx]);
|
||||
}
|
||||
if (ii.min.x == MAX_USHORT)
|
||||
if (ii.min.x == MAX_USHORT) {
|
||||
// This is an invalid sphere (out of image). These spheres have
|
||||
// maximum depth. Since we ordered the spheres by earliest possible
|
||||
// intersection depth we re certain that there will no other sphere
|
||||
// that is relevant after this one.
|
||||
loading_done = true;
|
||||
}
|
||||
}
|
||||
// Reset n_pixels_done.
|
||||
n_pixels_done = 0;
|
||||
thread_block.sync(); // Make sure n_loaded is updated.
|
||||
if (n_loaded > RENDER_BUFFER_LOAD_THRESH) {
|
||||
// The load buffer is full enough. Draw.
|
||||
if (thread_block.thread_rank() == 0)
|
||||
if (thread_block.thread_rank() == 0) {
|
||||
n_balls_loaded += n_loaded;
|
||||
}
|
||||
max_closest_possible_intersection = 0.f;
|
||||
// This excludes threads outside of the image boundary. Also, it reduces
|
||||
// block artifacts.
|
||||
@@ -290,8 +293,9 @@ GLOBAL void render(
|
||||
uint warp_done = thread_warp.ballot(done);
|
||||
int warp_done_bit_cnt = POPC(warp_done);
|
||||
#endif //__CUDACC__ && __HIP_PLATFORM_AMD__
|
||||
if (thread_warp.thread_rank() == 0)
|
||||
if (thread_warp.thread_rank() == 0) {
|
||||
ATOMICADD_B(&n_pixels_done, warp_done_bit_cnt);
|
||||
}
|
||||
// This sync is necessary to keep n_loaded until all threads are done with
|
||||
// painting.
|
||||
thread_block.sync();
|
||||
@@ -299,8 +303,9 @@ GLOBAL void render(
|
||||
}
|
||||
thread_block.sync();
|
||||
}
|
||||
if (thread_block.thread_rank() == 0)
|
||||
if (thread_block.thread_rank() == 0) {
|
||||
n_balls_loaded += n_loaded;
|
||||
}
|
||||
PULSAR_LOG_DEV_PIX(
|
||||
PULSAR_LOG_RENDER_PIX,
|
||||
"render|loaded %d balls in total.\n",
|
||||
@@ -386,8 +391,9 @@ GLOBAL void render(
|
||||
static_cast<float>(tracker.get_n_hits());
|
||||
} else {
|
||||
float sm_d_normfac = FRCP(FMAX(sm_d, FEPS));
|
||||
for (uint c_id = 0; c_id < cam_norm.n_channels; ++c_id)
|
||||
for (uint c_id = 0; c_id < cam_norm.n_channels; ++c_id) {
|
||||
result[c_id] *= sm_d_normfac;
|
||||
}
|
||||
int write_loc = (coord_y - cam_norm.film_border_top) * cam_norm.film_width *
|
||||
(3 + 2 * n_track) +
|
||||
(coord_x - cam_norm.film_border_left) * (3 + 2 * n_track);
|
||||
|
||||
@@ -860,8 +860,9 @@ std::tuple<torch::Tensor, torch::Tensor> Renderer::forward(
|
||||
? (cudaStream_t) nullptr
|
||||
#endif
|
||||
: (cudaStream_t) nullptr);
|
||||
if (mode == 1)
|
||||
if (mode == 1) {
|
||||
results[batch_i] = results[batch_i].slice(2, 0, 1, 1);
|
||||
}
|
||||
forw_infos[batch_i] = from_blob(
|
||||
this->renderer_vec[batch_i].forw_info_d,
|
||||
{this->renderer_vec[0].cam.film_height,
|
||||
|
||||
@@ -128,8 +128,9 @@ struct Renderer {
|
||||
stream << "pulsar::Renderer[";
|
||||
// Device info.
|
||||
stream << self.device_type;
|
||||
if (self.device_index != -1)
|
||||
if (self.device_index != -1) {
|
||||
stream << ", ID " << self.device_index;
|
||||
}
|
||||
stream << "]";
|
||||
return stream;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ auto ComputeFaceAreas(const torch::Tensor& face_verts) {
|
||||
return face_areas;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper function to use with std::find_if to find the index of any
|
||||
// values in the top k struct which match a given idx.
|
||||
struct IsNeighbor {
|
||||
@@ -118,7 +120,6 @@ struct IsNeighbor {
|
||||
int neighbor_idx;
|
||||
};
|
||||
|
||||
namespace {
|
||||
void RasterizeMeshesNaiveCpu_worker(
|
||||
const int start_yi,
|
||||
const int end_yi,
|
||||
|
||||
@@ -21,7 +21,6 @@ from typing import (
|
||||
)
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameData
|
||||
from pytorch3d.implicitron.dataset.utils import GenericWorkaround
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ from typing import (
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset import orm_types, types
|
||||
from pytorch3d.implicitron.dataset.utils import (
|
||||
adjust_camera_to_bbox_crop_,
|
||||
|
||||
@@ -38,7 +38,6 @@ from pytorch3d.implicitron.dataset.utils import is_known_frame_scalar
|
||||
from pytorch3d.implicitron.tools.config import registry, ReplaceableBase
|
||||
from pytorch3d.renderer.camera_utils import join_cameras_as_batch
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
@@ -327,9 +326,9 @@ class JsonIndexDataset(DatasetBase, ReplaceableBase):
|
||||
assert os.path.normpath(
|
||||
# pyre-ignore[16]
|
||||
self.frame_annots[idx]["frame_annotation"].image.path
|
||||
) == os.path.normpath(
|
||||
path
|
||||
), f"Inconsistent frame indices {seq_name, frame_no, path}."
|
||||
) == os.path.normpath(path), (
|
||||
f"Inconsistent frame indices {seq_name, frame_no, path}."
|
||||
)
|
||||
return idx
|
||||
|
||||
dataset_idx = [
|
||||
|
||||
@@ -21,7 +21,6 @@ from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
from .dataset_map_provider import DatasetMap, DatasetMapProviderBase, PathManagerFactory
|
||||
from .json_index_dataset import JsonIndexDataset
|
||||
|
||||
from .utils import (
|
||||
DATASET_TYPE_KNOWN,
|
||||
DATASET_TYPE_TEST,
|
||||
|
||||
@@ -18,7 +18,6 @@ from typing import Dict, List, Optional, Tuple, Type, Union
|
||||
|
||||
import numpy as np
|
||||
from iopath.common.file_io import PathManager
|
||||
|
||||
from omegaconf import DictConfig
|
||||
from pytorch3d.implicitron.dataset.dataset_map_provider import (
|
||||
DatasetMap,
|
||||
@@ -31,7 +30,6 @@ from pytorch3d.implicitron.tools.config import (
|
||||
registry,
|
||||
run_auto_creation,
|
||||
)
|
||||
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import torch
|
||||
from pytorch3d.implicitron.tools.config import registry
|
||||
|
||||
from .load_llff import load_llff_data
|
||||
|
||||
from .single_sequence_dataset import (
|
||||
_interpret_blender_cameras,
|
||||
SingleSceneDatasetMapProviderBase,
|
||||
|
||||
@@ -8,7 +8,6 @@ import os
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import struct
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
|
||||
from pytorch3d.implicitron.dataset.types import (
|
||||
DepthAnnotation,
|
||||
ImageAnnotation,
|
||||
@@ -22,7 +21,6 @@ from pytorch3d.implicitron.dataset.types import (
|
||||
VideoAnnotation,
|
||||
ViewpointAnnotation,
|
||||
)
|
||||
|
||||
from sqlalchemy import LargeBinary
|
||||
from sqlalchemy.orm import (
|
||||
composite,
|
||||
|
||||
@@ -10,7 +10,6 @@ import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import urllib
|
||||
from dataclasses import dataclass, Field, field
|
||||
from typing import (
|
||||
@@ -32,13 +31,11 @@ import pandas as pd
|
||||
import sqlalchemy as sa
|
||||
import torch
|
||||
from pytorch3d.implicitron.dataset.dataset_base import DatasetBase
|
||||
|
||||
from pytorch3d.implicitron.dataset.frame_data import (
|
||||
FrameData,
|
||||
FrameDataBuilder, # noqa
|
||||
FrameDataBuilderBase,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.tools.config import (
|
||||
registry,
|
||||
ReplaceableBase,
|
||||
@@ -486,9 +483,10 @@ class SqlIndexDataset(DatasetBase, ReplaceableBase):
|
||||
*self._get_pick_filters(),
|
||||
*self._get_exclude_filters(),
|
||||
]
|
||||
if self.pick_sequences_sql_clause:
|
||||
if pick_sequences_sql_clause := self.pick_sequences_sql_clause:
|
||||
print("Applying the custom SQL clause.")
|
||||
where_conditions.append(sa.text(self.pick_sequences_sql_clause))
|
||||
# pyre-ignore[6]: TextClause is compatible with where conditions
|
||||
where_conditions.append(sa.text(pick_sequences_sql_clause))
|
||||
|
||||
def add_where(stmt):
|
||||
return stmt.where(*where_conditions) if where_conditions else stmt
|
||||
@@ -508,6 +506,7 @@ class SqlIndexDataset(DatasetBase, ReplaceableBase):
|
||||
|
||||
subquery = add_where(subquery).subquery()
|
||||
stmt = sa.select(subquery.c.sequence_name).where(
|
||||
# pyre-ignore[6]: SQLAlchemy column comparison returns ColumnElement, not bool
|
||||
subquery.c.row_number <= self.limit_sequences_per_category_to
|
||||
)
|
||||
|
||||
@@ -636,9 +635,10 @@ class SqlIndexDataset(DatasetBase, ReplaceableBase):
|
||||
)
|
||||
)
|
||||
|
||||
if self.pick_frames_sql_clause:
|
||||
if pick_frames_sql_clause := self.pick_frames_sql_clause:
|
||||
logger.info("Applying the custom SQL clause.")
|
||||
pick_frames_criteria.append(sa.text(self.pick_frames_sql_clause))
|
||||
# pyre-ignore[6]: TextClause is compatible with where conditions
|
||||
pick_frames_criteria.append(sa.text(pick_frames_sql_clause))
|
||||
|
||||
if pick_frames_criteria:
|
||||
index = self._pick_frames_by_criteria(index, pick_frames_criteria)
|
||||
@@ -701,9 +701,10 @@ class SqlIndexDataset(DatasetBase, ReplaceableBase):
|
||||
)
|
||||
)
|
||||
|
||||
if self.pick_frames_sql_clause:
|
||||
if pick_frames_sql_clause := self.pick_frames_sql_clause:
|
||||
logger.info(" applying custom SQL clause")
|
||||
where_conditions.append(sa.text(self.pick_frames_sql_clause))
|
||||
# pyre-ignore[6]: TextClause is compatible with where conditions
|
||||
where_conditions.append(sa.text(pick_frames_sql_clause))
|
||||
|
||||
if where_conditions:
|
||||
stmt = stmt.where(*where_conditions)
|
||||
|
||||
@@ -12,9 +12,7 @@ import os
|
||||
from typing import List, Optional, Tuple, Type
|
||||
|
||||
import numpy as np
|
||||
|
||||
from omegaconf import DictConfig, OmegaConf
|
||||
|
||||
from pytorch3d.implicitron.dataset.dataset_map_provider import (
|
||||
DatasetMap,
|
||||
DatasetMapProviderBase,
|
||||
|
||||
@@ -18,7 +18,6 @@ from pytorch3d.implicitron.dataset.dataset_base import DatasetBase
|
||||
from pytorch3d.implicitron.dataset.dataset_map_provider import DatasetMap
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameData
|
||||
from pytorch3d.implicitron.tools.config import registry, run_auto_creation
|
||||
|
||||
from torch.utils.data import DataLoader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,7 +15,6 @@ from typing import List, Optional, Tuple, TypeVar, Union
|
||||
import numpy as np
|
||||
import torch
|
||||
from PIL import Image
|
||||
|
||||
from pytorch3d.io import IO
|
||||
from pytorch3d.renderer.cameras import PerspectiveCameras
|
||||
from pytorch3d.structures.pointclouds import Pointclouds
|
||||
|
||||
@@ -14,7 +14,6 @@ import warnings
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
import tqdm
|
||||
from pytorch3d.implicitron.evaluation import evaluate_new_view_synthesis as evaluate
|
||||
from pytorch3d.implicitron.models.base_model import EvaluationMode, ImplicitronModelBase
|
||||
|
||||
@@ -10,7 +10,6 @@ from dataclasses import dataclass, field
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import EvaluationMode
|
||||
from pytorch3d.implicitron.tools.config import ReplaceableBase
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
@@ -16,7 +16,6 @@ from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
|
||||
|
||||
import torch
|
||||
from omegaconf import DictConfig
|
||||
|
||||
from pytorch3d.implicitron.models.base_model import (
|
||||
ImplicitronModelBase,
|
||||
ImplicitronRender,
|
||||
@@ -28,7 +27,6 @@ from pytorch3d.implicitron.models.metrics import (
|
||||
RegularizationMetricsBase,
|
||||
ViewMetricsBase,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import (
|
||||
BaseRenderer,
|
||||
EvaluationMode,
|
||||
@@ -38,7 +36,6 @@ from pytorch3d.implicitron.models.renderer.base import (
|
||||
RenderSamplingMode,
|
||||
)
|
||||
from pytorch3d.implicitron.models.renderer.ray_sampler import RaySamplerBase
|
||||
|
||||
from pytorch3d.implicitron.models.utils import (
|
||||
apply_chunked,
|
||||
chunk_generator,
|
||||
@@ -53,7 +50,6 @@ from pytorch3d.implicitron.tools.config import (
|
||||
registry,
|
||||
run_auto_creation,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.tools.rasterize_mc import rasterize_sparse_ray_bundle
|
||||
from pytorch3d.renderer import utils as rend_utils
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
@@ -10,7 +10,6 @@ from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
|
||||
from pytorch3d.implicitron.tools.config import ReplaceableBase
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
|
||||
@@ -16,14 +16,11 @@ This file contains
|
||||
|
||||
import logging
|
||||
from dataclasses import field
|
||||
|
||||
from enum import Enum
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from omegaconf import DictConfig
|
||||
|
||||
from pytorch3d.implicitron.tools.config import (
|
||||
Configurable,
|
||||
registry,
|
||||
|
||||
@@ -11,7 +11,6 @@ import torch
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
from pytorch3d.implicitron.tools.config import registry
|
||||
from pytorch3d.renderer.implicit import HarmonicEmbedding
|
||||
|
||||
from torch import nn
|
||||
|
||||
from .base import ImplicitFunctionBase
|
||||
|
||||
@@ -21,7 +21,6 @@ from pytorch3d.renderer.implicit import HarmonicEmbedding
|
||||
from pytorch3d.renderer.implicit.utils import ray_bundle_to_ray_points
|
||||
|
||||
from .base import ImplicitFunctionBase
|
||||
|
||||
from .decoding_functions import ( # noqa
|
||||
_xavier_init,
|
||||
MLPWithInputSkips,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
from typing import Callable, Optional
|
||||
|
||||
import torch
|
||||
|
||||
import torch.nn.functional as F
|
||||
from pytorch3d.common.compat import prod
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
|
||||
@@ -13,9 +13,7 @@ from dataclasses import fields
|
||||
from typing import Callable, Dict, Optional, Tuple
|
||||
|
||||
import torch
|
||||
|
||||
from omegaconf import DictConfig
|
||||
|
||||
from pytorch3d.implicitron.models.implicit_function.base import ImplicitFunctionBase
|
||||
from pytorch3d.implicitron.models.implicit_function.decoding_functions import (
|
||||
DecoderFunctionBase,
|
||||
|
||||
@@ -17,7 +17,6 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, TYPE_CHECKING, Un
|
||||
|
||||
import torch
|
||||
from omegaconf import DictConfig
|
||||
|
||||
from pytorch3d.implicitron.models.base_model import (
|
||||
ImplicitronModelBase,
|
||||
ImplicitronRender,
|
||||
@@ -28,7 +27,6 @@ from pytorch3d.implicitron.models.metrics import (
|
||||
RegularizationMetricsBase,
|
||||
ViewMetricsBase,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import (
|
||||
BaseRenderer,
|
||||
EvaluationMode,
|
||||
@@ -50,7 +48,6 @@ from pytorch3d.implicitron.tools.config import (
|
||||
registry,
|
||||
run_auto_creation,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.tools.rasterize_mc import rasterize_sparse_ray_bundle
|
||||
from pytorch3d.renderer import utils as rend_utils
|
||||
from pytorch3d.renderer.cameras import CamerasBase
|
||||
|
||||
@@ -11,7 +11,6 @@ import copy
|
||||
import torch
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
from pytorch3d.implicitron.tools.config import Configurable, expand_args_fields
|
||||
|
||||
from pytorch3d.renderer.implicit.sample_pdf import sample_pdf
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import torch
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
from pytorch3d.implicitron.tools.config import enable_get_default_args
|
||||
from pytorch3d.renderer.implicit import HarmonicEmbedding
|
||||
|
||||
from torch import nn
|
||||
|
||||
|
||||
|
||||
@@ -17,11 +17,8 @@ from typing import Any, Dict, Optional, Tuple
|
||||
import torch
|
||||
import tqdm
|
||||
from pytorch3d.common.compat import prod
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
|
||||
from pytorch3d.implicitron.tools import image_utils
|
||||
|
||||
from pytorch3d.implicitron.tools.utils import cat_dataclass
|
||||
|
||||
|
||||
@@ -83,9 +80,9 @@ def preprocess_input(
|
||||
|
||||
if mask_depths and fg_mask is not None and depth_map is not None:
|
||||
# mask the depths
|
||||
assert (
|
||||
mask_threshold > 0.0
|
||||
), "Depths should be masked only with thresholded masks"
|
||||
assert mask_threshold > 0.0, (
|
||||
"Depths should be masked only with thresholded masks"
|
||||
)
|
||||
warnings.warn("Masking depths!")
|
||||
depth_map = depth_map * fg_mask
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import math
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import pytorch3d
|
||||
|
||||
import torch
|
||||
from pytorch3d.ops import packed_to_padded
|
||||
from pytorch3d.renderer import PerspectiveCameras
|
||||
|
||||
@@ -499,7 +499,7 @@ class StatsJSONEncoder(json.JSONEncoder):
|
||||
return enc
|
||||
else:
|
||||
raise TypeError(
|
||||
f"Object of type {o.__class__.__name__} " f"is not JSON serializable"
|
||||
f"Object of type {o.__class__.__name__} is not JSON serializable"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from PIL import Image
|
||||
|
||||
_NO_TORCHVISION = False
|
||||
|
||||
@@ -796,7 +796,7 @@ def save_obj(
|
||||
# Create .mtl file with the material name and texture map filename
|
||||
# TODO: enable material properties to also be saved.
|
||||
with _open_file(mtl_path, path_manager, "w") as f_mtl:
|
||||
lines = f"newmtl mesh\n" f"map_Kd {output_path.stem}.png\n"
|
||||
lines = f"newmtl mesh\nmap_Kd {output_path.stem}.png\n"
|
||||
f_mtl.write(lines)
|
||||
|
||||
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
|
||||
|
||||
from .chamfer import chamfer_distance
|
||||
|
||||
from .mesh_edge_loss import mesh_edge_loss
|
||||
|
||||
from .mesh_laplacian_smoothing import mesh_laplacian_smoothing
|
||||
|
||||
from .mesh_normal_consistency import mesh_normal_consistency
|
||||
from .point_mesh_distance import point_mesh_edge_distance, point_mesh_face_distance
|
||||
|
||||
|
||||
@@ -114,9 +114,7 @@ def mesh_laplacian_smoothing(meshes, method: str = "uniform"):
|
||||
if method == "cot":
|
||||
norm_w = torch.sparse.sum(L, dim=1).to_dense().view(-1, 1)
|
||||
idx = norm_w > 0
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and
|
||||
# `Tensor`.
|
||||
norm_w[idx] = 1.0 / norm_w[idx]
|
||||
norm_w[idx] = torch.reciprocal(norm_w[idx])
|
||||
else:
|
||||
L_sum = torch.sparse.sum(L, dim=1).to_dense().view(-1, 1)
|
||||
norm_w = 0.25 * inv_areas
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
# pyre-unsafe
|
||||
|
||||
import torch
|
||||
from pytorch3d import _C
|
||||
from pytorch3d.structures import Meshes, Pointclouds
|
||||
from torch.autograd import Function
|
||||
@@ -302,8 +303,7 @@ def point_mesh_edge_distance(meshes: Meshes, pcls: Pointclouds):
|
||||
point_to_cloud_idx = pcls.packed_to_cloud_idx() # (sum(P_i), )
|
||||
num_points_per_cloud = pcls.num_points_per_cloud() # (N,)
|
||||
weights_p = num_points_per_cloud.gather(0, point_to_cloud_idx)
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
weights_p = 1.0 / weights_p.float()
|
||||
weights_p = torch.reciprocal(weights_p.float())
|
||||
point_to_edge = point_to_edge * weights_p
|
||||
point_dist = point_to_edge.sum() / N
|
||||
|
||||
@@ -377,8 +377,7 @@ def point_mesh_face_distance(
|
||||
point_to_cloud_idx = pcls.packed_to_cloud_idx() # (sum(P_i),)
|
||||
num_points_per_cloud = pcls.num_points_per_cloud() # (N,)
|
||||
weights_p = num_points_per_cloud.gather(0, point_to_cloud_idx)
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
weights_p = 1.0 / weights_p.float()
|
||||
weights_p = torch.reciprocal(weights_p.float())
|
||||
point_to_face = point_to_face * weights_p
|
||||
point_dist = point_to_face.sum() / N
|
||||
|
||||
|
||||
@@ -8,17 +8,14 @@
|
||||
|
||||
from .ball_query import ball_query
|
||||
from .cameras_alignment import corresponding_cameras_alignment
|
||||
|
||||
from .cubify import cubify
|
||||
from .graph_conv import GraphConv
|
||||
from .interp_face_attrs import interpolate_face_attributes
|
||||
from .iou_box3d import box3d_overlap
|
||||
from .knn import knn_gather, knn_points
|
||||
from .laplacian_matrices import cot_laplacian, laplacian, norm_laplacian
|
||||
|
||||
from .mesh_face_areas_normals import mesh_face_areas_normals
|
||||
from .mesh_filtering import taubin_smoothing
|
||||
|
||||
from .packed_to_padded import packed_to_padded, padded_to_packed
|
||||
from .perspective_n_points import efficient_pnp
|
||||
from .points_alignment import corresponding_points_alignment, iterative_closest_point
|
||||
@@ -30,9 +27,7 @@ from .points_to_volumes import (
|
||||
add_pointclouds_to_volumes,
|
||||
add_points_features_to_volume_densities_features,
|
||||
)
|
||||
|
||||
from .sample_farthest_points import sample_farthest_points
|
||||
|
||||
from .sample_points_from_meshes import sample_points_from_meshes
|
||||
from .subdivide_meshes import SubdivideMeshes
|
||||
from .utils import (
|
||||
@@ -42,7 +37,6 @@ from .utils import (
|
||||
is_pointclouds,
|
||||
wmean,
|
||||
)
|
||||
|
||||
from .vert_align import vert_align
|
||||
|
||||
|
||||
|
||||
@@ -11,9 +11,7 @@ from typing import Optional
|
||||
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
from pytorch3d.common.compat import meshgrid_ij
|
||||
|
||||
from pytorch3d.structures import Meshes
|
||||
|
||||
|
||||
|
||||
@@ -55,11 +55,9 @@ def laplacian(verts: torch.Tensor, edges: torch.Tensor) -> torch.Tensor:
|
||||
# We construct the Laplacian matrix by adding the non diagonal values
|
||||
# i.e. L[i, j] = 1 ./ deg(i) if (i, j) is an edge
|
||||
deg0 = deg[e0]
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
deg0 = torch.where(deg0 > 0.0, 1.0 / deg0, deg0)
|
||||
deg0 = torch.where(deg0 > 0.0, torch.reciprocal(deg0), deg0)
|
||||
deg1 = deg[e1]
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
deg1 = torch.where(deg1 > 0.0, 1.0 / deg1, deg1)
|
||||
deg1 = torch.where(deg1 > 0.0, torch.reciprocal(deg1), deg1)
|
||||
val = torch.cat([deg0, deg1])
|
||||
L = torch.sparse_coo_tensor(idx, val, (V, V), dtype=torch.float32)
|
||||
|
||||
@@ -137,8 +135,7 @@ def cot_laplacian(
|
||||
val = torch.stack([area] * 3, dim=1).view(-1)
|
||||
inv_areas.scatter_add_(0, idx, val)
|
||||
idx = inv_areas > 0
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
inv_areas[idx] = 1.0 / inv_areas[idx]
|
||||
inv_areas[idx] = torch.reciprocal(inv_areas[idx])
|
||||
inv_areas = inv_areas.view(-1, 1)
|
||||
|
||||
return L, inv_areas
|
||||
|
||||
@@ -16,9 +16,7 @@ import sys
|
||||
from typing import Tuple, Union
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.ops.mesh_face_areas_normals import mesh_face_areas_normals
|
||||
|
||||
from pytorch3d.ops.packed_to_padded import packed_to_padded
|
||||
from pytorch3d.renderer.mesh.rasterizer import Fragments as MeshFragments
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ from .mesh import (
|
||||
TexturesUV,
|
||||
TexturesVertex,
|
||||
)
|
||||
|
||||
from .points import (
|
||||
AlphaCompositor,
|
||||
NormWeightedCompositor,
|
||||
|
||||
@@ -153,12 +153,12 @@ def _pulsar_from_opencv_projection(
|
||||
# Check image sizes.
|
||||
image_w = image_size_wh[0, 0]
|
||||
image_h = image_size_wh[0, 1]
|
||||
assert torch.all(
|
||||
image_size_wh[:, 0] == image_w
|
||||
), "All images in a batch must have the same width!"
|
||||
assert torch.all(
|
||||
image_size_wh[:, 1] == image_h
|
||||
), "All images in a batch must have the same height!"
|
||||
assert torch.all(image_size_wh[:, 0] == image_w), (
|
||||
"All images in a batch must have the same width!"
|
||||
)
|
||||
assert torch.all(image_size_wh[:, 1] == image_h), (
|
||||
"All images in a batch must have the same height!"
|
||||
)
|
||||
# Focal length.
|
||||
fx = camera_matrix[:, 0, 0].unsqueeze(1)
|
||||
fy = camera_matrix[:, 1, 1].unsqueeze(1)
|
||||
|
||||
@@ -629,10 +629,8 @@ class FoVPerspectiveCameras(CamerasBase):
|
||||
# so the so the z sign is 1.0.
|
||||
z_sign = 1.0
|
||||
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
K[:, 0, 0] = 2.0 * znear / (max_x - min_x)
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
K[:, 1, 1] = 2.0 * znear / (max_y - min_y)
|
||||
K[:, 0, 0] = torch.div(2.0 * znear, max_x - min_x)
|
||||
K[:, 1, 1] = torch.div(2.0 * znear, max_y - min_y)
|
||||
K[:, 0, 2] = (max_x + min_x) / (max_x - min_x)
|
||||
K[:, 1, 2] = (max_y + min_y) / (max_y - min_y)
|
||||
K[:, 3, 2] = z_sign * ones
|
||||
@@ -1178,9 +1176,7 @@ class PerspectiveCameras(CamerasBase):
|
||||
xy_inv_depth = torch.cat(
|
||||
# pyre-fixme[6]: For 1st argument expected `Union[List[Tensor],
|
||||
# tuple[Tensor, ...]]` but got `Tuple[Tensor, float]`.
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and
|
||||
# `Tensor`.
|
||||
(xy_depth[..., :2], 1.0 / xy_depth[..., 2:3]),
|
||||
(xy_depth[..., :2], torch.reciprocal(xy_depth[..., 2:3])),
|
||||
dim=-1, # type: ignore
|
||||
)
|
||||
return unprojection_transform.transform_points(xy_inv_depth)
|
||||
|
||||
@@ -12,7 +12,6 @@ from .clip import (
|
||||
ClippedFaces,
|
||||
convert_clipped_rasterization_to_original_faces,
|
||||
)
|
||||
|
||||
from .rasterize_meshes import rasterize_meshes
|
||||
from .rasterizer import MeshRasterizer, RasterizationSettings
|
||||
from .renderer import MeshRenderer, MeshRendererWithFragments
|
||||
|
||||
@@ -434,13 +434,7 @@ def clip_faces(
|
||||
# These will then be filled in for each case.
|
||||
###########################################
|
||||
F_clipped = (
|
||||
F
|
||||
# pyre-fixme[58]: `+` is not supported for operand types `int` and
|
||||
# `Union[bool, float, int]`.
|
||||
+ faces_delta_cum[-1].item()
|
||||
# pyre-fixme[58]: `+` is not supported for operand types `int` and
|
||||
# `Union[bool, float, int]`.
|
||||
+ faces_delta[-1].item()
|
||||
F + int(faces_delta_cum[-1].item()) + int(faces_delta[-1].item())
|
||||
) # Total number of faces in the new Meshes
|
||||
face_verts_clipped = torch.zeros(
|
||||
(F_clipped, 3, 3), dtype=face_verts_unclipped.dtype, device=device
|
||||
|
||||
@@ -14,7 +14,6 @@ import torch
|
||||
from pytorch3d import _C
|
||||
|
||||
from ..utils import parse_image_size
|
||||
|
||||
from .clip import (
|
||||
clip_faces,
|
||||
ClipFrustum,
|
||||
|
||||
@@ -71,9 +71,7 @@ def _list_to_padded_wrapper(
|
||||
# pyre-fixme[6]: For 2nd param expected `int` but got `Union[bool, float, int]`.
|
||||
x_reshaped.append(y.reshape(-1, D))
|
||||
x_padded = list_to_padded(x_reshaped, pad_size=pad_size, pad_value=pad_value)
|
||||
# pyre-fixme[58]: `+` is not supported for operand types `Tuple[int, int]` and
|
||||
# `Size`.
|
||||
return x_padded.reshape((N, -1) + reshape_dims)
|
||||
return x_padded.reshape((N, -1) + tuple(reshape_dims))
|
||||
|
||||
|
||||
def _padded_to_list_wrapper(
|
||||
@@ -104,9 +102,7 @@ def _padded_to_list_wrapper(
|
||||
# pyre-fixme[6]: For 3rd param expected `int` but got `Union[bool, float, int]`.
|
||||
x_reshaped = x.reshape(N, M, D)
|
||||
x_list = padded_to_list(x_reshaped, split_size=split_size)
|
||||
# pyre-fixme[58]: `+` is not supported for operand types `Tuple[typing.Any]` and
|
||||
# `Size`.
|
||||
x_list = [xl.reshape((xl.shape[0],) + reshape_dims) for xl in x_list]
|
||||
x_list = [xl.reshape((xl.shape[0],) + tuple(reshape_dims)) for xl in x_list]
|
||||
return x_list
|
||||
|
||||
|
||||
@@ -625,9 +621,7 @@ class TexturesAtlas(TexturesBase):
|
||||
of length `k`.
|
||||
"""
|
||||
if len(faces_ids_list) != len(self.atlas_list()):
|
||||
raise IndexError(
|
||||
"faces_ids_list must be of " "the same length as atlas_list."
|
||||
)
|
||||
raise IndexError("faces_ids_list must be of the same length as atlas_list.")
|
||||
|
||||
sub_features = []
|
||||
for atlas, faces_ids in zip(self.atlas_list(), faces_ids_list):
|
||||
@@ -1657,7 +1651,7 @@ class TexturesUV(TexturesBase):
|
||||
raise NotImplementedError("This function does not support multiple maps.")
|
||||
if len(faces_ids_list) != len(self.faces_uvs_padded()):
|
||||
raise IndexError(
|
||||
"faces_uvs_padded must be of " "the same length as face_ids_list."
|
||||
"faces_uvs_padded must be of the same length as face_ids_list."
|
||||
)
|
||||
|
||||
sub_faces_uvs, sub_verts_uvs, sub_maps = [], [], []
|
||||
@@ -1871,7 +1865,7 @@ class TexturesVertex(TexturesBase):
|
||||
"""
|
||||
if len(vertex_ids_list) != len(self.verts_features_list()):
|
||||
raise IndexError(
|
||||
"verts_features_list must be of " "the same length as vertex_ids_list."
|
||||
"verts_features_list must be of the same length as vertex_ids_list."
|
||||
)
|
||||
|
||||
sub_features = []
|
||||
|
||||
@@ -24,7 +24,6 @@ from typing import Any, Dict
|
||||
|
||||
os.environ["PYOPENGL_PLATFORM"] = "egl"
|
||||
import OpenGL.EGL as egl # noqa
|
||||
|
||||
import pycuda.driver as cuda # noqa
|
||||
from OpenGL._opaque import opaque_pointer_cls # noqa
|
||||
from OpenGL.raw.EGL._errors import EGLError # noqa
|
||||
|
||||
@@ -17,15 +17,12 @@ import numpy as np
|
||||
import OpenGL.GL as gl
|
||||
import pycuda.gl
|
||||
import torch
|
||||
|
||||
import torch.nn as nn
|
||||
|
||||
from pytorch3d.structures.meshes import Meshes
|
||||
|
||||
from ..cameras import FoVOrthographicCameras, FoVPerspectiveCameras
|
||||
from ..mesh.rasterizer import Fragments, RasterizationSettings
|
||||
from ..utils import parse_image_size
|
||||
|
||||
from .opengl_utils import _torch_to_opengl, global_device_context_store
|
||||
|
||||
# Shader strings, used below to compile an OpenGL program.
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
import torch
|
||||
|
||||
from .compositor import AlphaCompositor, NormWeightedCompositor
|
||||
|
||||
from .pulsar.unified import PulsarPointsRenderer
|
||||
|
||||
from .rasterize_points import rasterize_points
|
||||
from .rasterizer import PointsRasterizationSettings, PointsRasterizer
|
||||
from .renderer import PointsRenderer
|
||||
|
||||
@@ -11,7 +11,6 @@ from typing import List, Optional, Tuple, Union
|
||||
import numpy as np
|
||||
import torch
|
||||
from pytorch3d import _C
|
||||
|
||||
from pytorch3d.renderer.mesh.rasterize_meshes import pix_to_non_square_ndc
|
||||
|
||||
from ..utils import parse_image_size
|
||||
|
||||
@@ -269,9 +269,7 @@ class TensorProperties(nn.Module):
|
||||
# to have the same shape as the input tensor.
|
||||
new_dims = len(tensor_dims) - len(idx_dims)
|
||||
new_shape = idx_dims + (1,) * new_dims
|
||||
# pyre-fixme[58]: `+` is not supported for operand types
|
||||
# `Tuple[int]` and `torch._C.Size`
|
||||
expand_dims = (-1,) + tensor_dims[1:]
|
||||
expand_dims = (-1,) + tuple(tensor_dims[1:])
|
||||
_batch_idx = _batch_idx.view(*new_shape)
|
||||
_batch_idx = _batch_idx.expand(*expand_dims)
|
||||
|
||||
|
||||
@@ -531,9 +531,9 @@ class Meshes:
|
||||
list of tensors of vertices of shape (V_n, 3).
|
||||
"""
|
||||
if self._verts_list is None:
|
||||
assert (
|
||||
self._verts_padded is not None
|
||||
), "verts_padded is required to compute verts_list."
|
||||
assert self._verts_padded is not None, (
|
||||
"verts_padded is required to compute verts_list."
|
||||
)
|
||||
self._verts_list = struct_utils.padded_to_list(
|
||||
self._verts_padded, self.num_verts_per_mesh().tolist()
|
||||
)
|
||||
@@ -547,9 +547,9 @@ class Meshes:
|
||||
list of tensors of faces of shape (F_n, 3).
|
||||
"""
|
||||
if self._faces_list is None:
|
||||
assert (
|
||||
self._faces_padded is not None
|
||||
), "faces_padded is required to compute faces_list."
|
||||
assert self._faces_padded is not None, (
|
||||
"faces_padded is required to compute faces_list."
|
||||
)
|
||||
self._faces_list = struct_utils.padded_to_list(
|
||||
self._faces_padded, self.num_faces_per_mesh().tolist()
|
||||
)
|
||||
@@ -925,9 +925,9 @@ class Meshes:
|
||||
|
||||
verts_list = self.verts_list()
|
||||
faces_list = self.faces_list()
|
||||
assert (
|
||||
faces_list is not None and verts_list is not None
|
||||
), "faces_list and verts_list arguments are required"
|
||||
assert faces_list is not None and verts_list is not None, (
|
||||
"faces_list and verts_list arguments are required"
|
||||
)
|
||||
|
||||
if self.isempty():
|
||||
self._faces_padded = torch.zeros(
|
||||
|
||||
@@ -433,9 +433,9 @@ class Pointclouds:
|
||||
list of tensors of points of shape (P_n, 3).
|
||||
"""
|
||||
if self._points_list is None:
|
||||
assert (
|
||||
self._points_padded is not None
|
||||
), "points_padded is required to compute points_list."
|
||||
assert self._points_padded is not None, (
|
||||
"points_padded is required to compute points_list."
|
||||
)
|
||||
points_list = []
|
||||
for i in range(self._N):
|
||||
points_list.append(
|
||||
|
||||
@@ -52,8 +52,7 @@ def quaternion_to_matrix(quaternions: torch.Tensor) -> torch.Tensor:
|
||||
Rotation matrices as tensor of shape (..., 3, 3).
|
||||
"""
|
||||
r, i, j, k = torch.unbind(quaternions, -1)
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
two_s = 2.0 / (quaternions * quaternions).sum(-1)
|
||||
two_s = torch.div(2.0, (quaternions * quaternions).sum(-1))
|
||||
|
||||
o = torch.stack(
|
||||
(
|
||||
@@ -137,18 +136,18 @@ def matrix_to_quaternion(matrix: torch.Tensor) -> torch.Tensor:
|
||||
# we produce the desired quaternion multiplied by each of r, i, j, k
|
||||
quat_by_rijk = torch.stack(
|
||||
[
|
||||
# pyre-fixme[58]: `**` is not supported for operand types `Tensor` and
|
||||
# `int`.
|
||||
torch.stack([q_abs[..., 0] ** 2, m21 - m12, m02 - m20, m10 - m01], dim=-1),
|
||||
# pyre-fixme[58]: `**` is not supported for operand types `Tensor` and
|
||||
# `int`.
|
||||
torch.stack([m21 - m12, q_abs[..., 1] ** 2, m10 + m01, m02 + m20], dim=-1),
|
||||
# pyre-fixme[58]: `**` is not supported for operand types `Tensor` and
|
||||
# `int`.
|
||||
torch.stack([m02 - m20, m10 + m01, q_abs[..., 2] ** 2, m12 + m21], dim=-1),
|
||||
# pyre-fixme[58]: `**` is not supported for operand types `Tensor` and
|
||||
# `int`.
|
||||
torch.stack([m10 - m01, m20 + m02, m21 + m12, q_abs[..., 3] ** 2], dim=-1),
|
||||
torch.stack(
|
||||
[torch.square(q_abs[..., 0]), m21 - m12, m02 - m20, m10 - m01], dim=-1
|
||||
),
|
||||
torch.stack(
|
||||
[m21 - m12, torch.square(q_abs[..., 1]), m10 + m01, m02 + m20], dim=-1
|
||||
),
|
||||
torch.stack(
|
||||
[m02 - m20, m10 + m01, torch.square(q_abs[..., 2]), m12 + m21], dim=-1
|
||||
),
|
||||
torch.stack(
|
||||
[m10 - m01, m20 + m02, m21 + m12, torch.square(q_abs[..., 3])], dim=-1
|
||||
),
|
||||
],
|
||||
dim=-2,
|
||||
)
|
||||
|
||||
@@ -623,9 +623,7 @@ class Scale(Transform3d):
|
||||
Return the inverse of self._matrix.
|
||||
"""
|
||||
xyz = torch.stack([self._matrix[:, i, i] for i in range(4)], dim=1)
|
||||
# pyre-fixme[58]: `/` is not supported for operand types `float` and `Tensor`.
|
||||
ixyz = 1.0 / xyz
|
||||
# pyre-fixme[6]: For 1st param expected `Tensor` but got `float`.
|
||||
ixyz = torch.reciprocal(xyz)
|
||||
imat = torch.diag_embed(ixyz, dim1=1, dim2=2)
|
||||
return imat
|
||||
|
||||
|
||||
@@ -12,11 +12,8 @@ from .camera_conversions import (
|
||||
pulsar_from_cameras_projection,
|
||||
pulsar_from_opencv_projection,
|
||||
)
|
||||
|
||||
from .checkerboard import checkerboard
|
||||
|
||||
from .ico_sphere import ico_sphere
|
||||
|
||||
from .torus import torus
|
||||
|
||||
|
||||
|
||||
15
setup.py
15
setup.py
@@ -75,6 +75,21 @@ def get_extensions():
|
||||
]
|
||||
if os.name != "nt":
|
||||
nvcc_args.append("-std=c++17")
|
||||
|
||||
# CUDA 13.0+ compatibility flags for pulsar.
|
||||
# Starting with CUDA 13, __global__ function visibility changed.
|
||||
# See: https://developer.nvidia.com/blog/
|
||||
# cuda-c-compiler-updates-impacting-elf-visibility-and-linkage/
|
||||
cuda_version = torch.version.cuda
|
||||
if cuda_version is not None:
|
||||
major = int(cuda_version.split(".")[0])
|
||||
if major >= 13:
|
||||
nvcc_args.extend(
|
||||
[
|
||||
"--device-entity-has-hidden-visibility=false",
|
||||
"-static-global-template-stub=false",
|
||||
]
|
||||
)
|
||||
if cub_home is None:
|
||||
prefix = os.environ.get("CONDA_PREFIX", None)
|
||||
if prefix is not None and os.path.isdir(prefix + "/include/cub"):
|
||||
|
||||
@@ -8,7 +8,6 @@ from itertools import product
|
||||
|
||||
import torch
|
||||
from fvcore.common.benchmark import benchmark
|
||||
|
||||
from pytorch3d.ops.ball_query import ball_query
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.models.utils import preprocess_input, weighted_sum_losses
|
||||
|
||||
|
||||
|
||||
@@ -11,12 +11,10 @@ from dataclasses import dataclass
|
||||
from itertools import product
|
||||
|
||||
import numpy as np
|
||||
|
||||
import torch
|
||||
from pytorch3d.implicitron.dataset.data_loader_map_provider import (
|
||||
DoublePoolBatchSampler,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.dataset.dataset_base import DatasetBase
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameData
|
||||
from pytorch3d.implicitron.dataset.scene_batch_sampler import SceneBatchSampler
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset.utils import (
|
||||
bbox_xywh_to_xyxy,
|
||||
bbox_xyxy_to_xywh,
|
||||
@@ -21,7 +19,6 @@ from pytorch3d.implicitron.dataset.utils import (
|
||||
rescale_bbox,
|
||||
resize_image,
|
||||
)
|
||||
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import os
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset.data_loader_map_provider import ( # noqa
|
||||
SequenceDataLoaderMapProvider,
|
||||
SimpleDataLoaderMapProvider,
|
||||
|
||||
@@ -8,7 +8,6 @@ import os
|
||||
import unittest
|
||||
|
||||
from pytorch3d.implicitron import eval_demo
|
||||
|
||||
from tests.common_testing import interactive_testing_requested
|
||||
|
||||
from .common_resources import CO3D_MANIFOLD_PATH
|
||||
|
||||
@@ -15,7 +15,6 @@ import unittest
|
||||
import lpips
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameData
|
||||
from pytorch3d.implicitron.dataset.json_index_dataset import JsonIndexDataset
|
||||
from pytorch3d.implicitron.evaluation.evaluate_new_view_synthesis import eval_batch
|
||||
|
||||
@@ -14,7 +14,6 @@ from typing import ClassVar, Optional, Type
|
||||
import pandas as pd
|
||||
import pkg_resources
|
||||
import sqlalchemy as sa
|
||||
|
||||
from pytorch3d.implicitron.dataset import types
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameData, GenericFrameDataBuilder
|
||||
from pytorch3d.implicitron.dataset.orm_types import (
|
||||
|
||||
@@ -12,7 +12,6 @@ from typing import List
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset import types
|
||||
from pytorch3d.implicitron.dataset.dataset_base import FrameData
|
||||
from pytorch3d.implicitron.dataset.frame_data import FrameDataBuilder
|
||||
@@ -29,7 +28,6 @@ from pytorch3d.implicitron.dataset.utils import (
|
||||
)
|
||||
from pytorch3d.implicitron.tools.config import get_default_args
|
||||
from pytorch3d.renderer.cameras import PerspectiveCameras
|
||||
|
||||
from tests.common_testing import TestCaseMixin
|
||||
from tests.implicitron.common_resources import get_skateboard_data
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import unittest
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
|
||||
import torch
|
||||
import torchvision
|
||||
from PIL import Image
|
||||
|
||||
@@ -13,7 +13,6 @@ from typing import Tuple
|
||||
import torch
|
||||
from pytorch3d.implicitron.dataset.json_index_dataset import JsonIndexDataset
|
||||
from pytorch3d.implicitron.dataset.visualize import get_implicitron_sequence_pointcloud
|
||||
|
||||
from pytorch3d.implicitron.models.visualization.render_flyaround import render_flyaround
|
||||
from pytorch3d.implicitron.tools.config import expand_args_fields
|
||||
from pytorch3d.implicitron.tools.point_cloud_utils import render_point_cloud_pytorch3d
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.base import (
|
||||
approximate_conical_frustum_as_gaussians,
|
||||
compute_3d_diagonal_covariance_gaussian,
|
||||
@@ -18,7 +16,6 @@ from pytorch3d.implicitron.models.renderer.base import (
|
||||
ImplicitronRayBundle,
|
||||
)
|
||||
from pytorch3d.implicitron.models.renderer.ray_sampler import AbstractMaskRaySampler
|
||||
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import unittest
|
||||
from itertools import product
|
||||
from typing import Tuple
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import torch
|
||||
@@ -18,7 +17,6 @@ from pytorch3d.implicitron.models.renderer.ray_sampler import (
|
||||
compute_radii,
|
||||
NearFarRaySampler,
|
||||
)
|
||||
|
||||
from pytorch3d.renderer.cameras import (
|
||||
CamerasBase,
|
||||
FoVOrthographicCameras,
|
||||
@@ -28,7 +26,6 @@ from pytorch3d.renderer.cameras import (
|
||||
)
|
||||
from pytorch3d.renderer.implicit.utils import HeterogeneousRayBundle
|
||||
from tests.common_camera_utils import init_random_cameras
|
||||
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
CAMERA_TYPES = (
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
from pytorch3d.implicitron.dataset.orm_types import ArrayTypeFactory, TupleTypeFactory
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import unittest
|
||||
|
||||
import torch
|
||||
from pytorch3d.implicitron.tools.point_cloud_utils import get_rgbd_point_cloud
|
||||
|
||||
from pytorch3d.renderer.cameras import PerspectiveCameras
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import unittest
|
||||
from itertools import product
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.models.renderer.ray_point_refiner import (
|
||||
apply_blurpool_on_weights,
|
||||
RayPointRefiner,
|
||||
|
||||
@@ -10,9 +10,7 @@ import unittest
|
||||
from collections import Counter
|
||||
|
||||
import pkg_resources
|
||||
|
||||
import torch
|
||||
|
||||
from pytorch3d.implicitron.dataset.sql_dataset import SqlIndexDataset
|
||||
|
||||
NO_BLOBS_KWARGS = {
|
||||
|
||||
@@ -16,7 +16,6 @@ from pytorch3d.implicitron.models.implicit_function.scene_representation_network
|
||||
from pytorch3d.implicitron.models.renderer.ray_sampler import ImplicitronRayBundle
|
||||
from pytorch3d.implicitron.tools.config import get_default_args
|
||||
from pytorch3d.renderer import PerspectiveCameras
|
||||
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
_BATCH_SIZE: int = 3
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from omegaconf import DictConfig, OmegaConf
|
||||
from pytorch3d.implicitron.models.implicit_function.voxel_grid_implicit_function import (
|
||||
VoxelGridImplicitFunction,
|
||||
)
|
||||
from pytorch3d.implicitron.models.renderer.base import ImplicitronRayBundle
|
||||
|
||||
from pytorch3d.implicitron.tools.config import expand_args_fields, get_default_args
|
||||
from pytorch3d.renderer import ray_bundle_to_ray_points
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
@@ -10,7 +10,6 @@ from typing import Optional, Tuple
|
||||
|
||||
import torch
|
||||
from omegaconf import DictConfig, OmegaConf
|
||||
|
||||
from pytorch3d.implicitron.models.implicit_function.utils import (
|
||||
interpolate_line,
|
||||
interpolate_plane,
|
||||
@@ -22,7 +21,6 @@ from pytorch3d.implicitron.models.implicit_function.voxel_grid import (
|
||||
VMFactorizedVoxelGrid,
|
||||
VoxelGridModule,
|
||||
)
|
||||
|
||||
from pytorch3d.implicitron.tools.config import expand_args_fields, get_default_args
|
||||
from tests.common_testing import TestCaseMixin
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ from pytorch3d.transforms.rotation_conversions import random_rotations
|
||||
from pytorch3d.transforms.so3 import so3_exp_map
|
||||
|
||||
from .common_camera_utils import init_random_cameras
|
||||
|
||||
from .common_testing import TestCaseMixin
|
||||
|
||||
|
||||
|
||||
@@ -673,9 +673,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
|
||||
|
||||
def test_load_simple_binary(self):
|
||||
for big_endian in [True, False]:
|
||||
verts = (
|
||||
"0 0 0 " "0 0 1 " "0 1 1 " "0 1 0 " "1 0 0 " "1 0 1 " "1 1 1 " "1 1 0"
|
||||
).split()
|
||||
verts = ("0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 1 0").split()
|
||||
faces = (
|
||||
"4 0 1 2 3 "
|
||||
"4 7 6 5 4 "
|
||||
@@ -688,7 +686,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
|
||||
"3 4 5 1"
|
||||
).split()
|
||||
short_one = b"\00\01" if big_endian else b"\01\00"
|
||||
mixed_data = b"\00\00" b"\03\03" + (short_one + b"\00\01\01\01" b"\00\02")
|
||||
mixed_data = b"\00\00\03\03" + (short_one + b"\00\01\01\01\00\02")
|
||||
minus_one_data = b"\xff" * 14
|
||||
endian_char = ">" if big_endian else "<"
|
||||
format = (
|
||||
|
||||
@@ -604,9 +604,9 @@ class TestRaysampling(TestCaseMixin, unittest.TestCase):
|
||||
# test weather they are of the correct shape
|
||||
for attr in ("origins", "directions", "lengths", "xys"):
|
||||
tensor = getattr(ray_bundle, attr)
|
||||
assert tensor.shape[:2] == torch.Size(
|
||||
(n_rays_total, 1)
|
||||
), tensor.shape
|
||||
assert tensor.shape[:2] == torch.Size((n_rays_total, 1)), (
|
||||
tensor.shape
|
||||
)
|
||||
|
||||
# if two camera ids are same than origins should also be the same
|
||||
# directions and xys are always different and lengths equal
|
||||
|
||||
@@ -12,7 +12,6 @@ Sanity checks for output images from the renderer.
|
||||
import os
|
||||
import unittest
|
||||
from collections import namedtuple
|
||||
|
||||
from itertools import product
|
||||
|
||||
import numpy as np
|
||||
|
||||
@@ -148,14 +148,14 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
for t_pair in ((t1, t2), (t1, t3), (t2, t3)):
|
||||
matrix1 = t_pair[0].get_matrix()
|
||||
matrix2 = t_pair[1].get_matrix()
|
||||
self.assertTrue(torch.allclose(matrix1, matrix2))
|
||||
self.assertClose(matrix1, matrix2)
|
||||
|
||||
def test_init_with_custom_matrix(self):
|
||||
for matrix in (torch.randn(10, 4, 4), torch.randn(4, 4)):
|
||||
t = Transform3d(matrix=matrix)
|
||||
self.assertTrue(t.device == matrix.device)
|
||||
self.assertTrue(t._matrix.dtype == matrix.dtype)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix.view(t._matrix.shape)))
|
||||
self.assertClose(t._matrix, matrix.view(t._matrix.shape))
|
||||
|
||||
def test_init_with_custom_matrix_errors(self):
|
||||
bad_shapes = [[10, 5, 4], [3, 4], [10, 4, 4, 1], [10, 4, 4, 2], [4, 4, 4, 3]]
|
||||
@@ -189,8 +189,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out_expected = torch.tensor(
|
||||
[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]]
|
||||
).view(1, 3, 3)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected))
|
||||
self.assertClose(points_out, points_out_expected)
|
||||
self.assertClose(normals_out, normals_out_expected)
|
||||
|
||||
@mock.patch.dict(os.environ, {"PYTORCH3D_CHECK_ROTATION_MATRICES": "1"}, clear=True)
|
||||
def test_rotate_check_rot_valid_on(self):
|
||||
@@ -206,8 +206,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out = t.transform_normals(normals)
|
||||
points_out_expected = torch.bmm(points, R)
|
||||
normals_out_expected = torch.bmm(normals, R)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected))
|
||||
self.assertClose(points_out, points_out_expected)
|
||||
self.assertClose(normals_out, normals_out_expected)
|
||||
|
||||
@mock.patch.dict(os.environ, {"PYTORCH3D_CHECK_ROTATION_MATRICES": "0"}, clear=True)
|
||||
def test_rotate_check_rot_valid_off(self):
|
||||
@@ -223,8 +223,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out = t.transform_normals(normals)
|
||||
points_out_expected = torch.bmm(points, R)
|
||||
normals_out_expected = torch.bmm(normals, R)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected))
|
||||
self.assertClose(points_out, points_out_expected)
|
||||
self.assertClose(normals_out, normals_out_expected)
|
||||
|
||||
def test_scale(self):
|
||||
t = Transform3d().scale(2.0).scale(0.5, 0.25, 1.0)
|
||||
@@ -242,8 +242,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out_expected = torch.tensor(
|
||||
[[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [1.0, 2.0, 0.0]]
|
||||
).view(1, 3, 3)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected))
|
||||
self.assertClose(points_out, points_out_expected)
|
||||
self.assertClose(normals_out, normals_out_expected)
|
||||
|
||||
def test_scale_translate(self):
|
||||
t = Transform3d().scale(2, 1, 3).translate(1, 2, 3)
|
||||
@@ -261,8 +261,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out_expected = torch.tensor(
|
||||
[[0.5, 0.0, 0.0], [0.0, 1.0, 0.0], [0.5, 1.0, 0.0]]
|
||||
).view(1, 3, 3)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected))
|
||||
self.assertClose(points_out, points_out_expected)
|
||||
self.assertClose(normals_out, normals_out_expected)
|
||||
|
||||
def test_rotate_axis_angle(self):
|
||||
t = Transform3d().rotate_axis_angle(90.0, axis="Z")
|
||||
@@ -280,8 +280,8 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
normals_out_expected = torch.tensor(
|
||||
[[0.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 1.0, 0.0]]
|
||||
).view(1, 3, 3)
|
||||
self.assertTrue(torch.allclose(points_out, points_out_expected, atol=1e-7))
|
||||
self.assertTrue(torch.allclose(normals_out, normals_out_expected, atol=1e-7))
|
||||
self.assertClose(points_out, points_out_expected, atol=1e-7)
|
||||
self.assertClose(normals_out, normals_out_expected, atol=1e-7)
|
||||
|
||||
def test_transform_points_fail(self):
|
||||
t1 = Scale(0.1, 0.1, 0.1)
|
||||
@@ -369,7 +369,7 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
|
||||
# assert all same
|
||||
for m in (m1, m2, m3, m4):
|
||||
self.assertTrue(torch.allclose(m, m5, atol=1e-3))
|
||||
self.assertClose(m, m5, atol=1e-3)
|
||||
|
||||
def _check_indexed_transforms(self, t3d, t3d_selected, indices):
|
||||
t3d_matrix = t3d.get_matrix()
|
||||
@@ -488,7 +488,7 @@ class TestTransform(TestCaseMixin, unittest.TestCase):
|
||||
self.assertClose(new_points, new_points_expect)
|
||||
|
||||
|
||||
class TestTranslate(unittest.TestCase):
|
||||
class TestTranslate(TestCaseMixin, unittest.TestCase):
|
||||
def test_python_scalar(self):
|
||||
t = Translate(0.2, 0.3, 0.4)
|
||||
matrix = torch.tensor(
|
||||
@@ -502,7 +502,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_torch_scalar(self):
|
||||
x = torch.tensor(0.2)
|
||||
@@ -520,7 +520,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_mixed_scalars(self):
|
||||
x = 0.2
|
||||
@@ -538,7 +538,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_torch_scalar_grads(self):
|
||||
# Make sure backprop works if we give torch scalars
|
||||
@@ -549,8 +549,8 @@ class TestTranslate(unittest.TestCase):
|
||||
t._matrix.sum().backward()
|
||||
self.assertTrue(hasattr(x, "grad"))
|
||||
self.assertTrue(hasattr(y, "grad"))
|
||||
self.assertTrue(torch.allclose(x.grad, x.new_ones(x.shape)))
|
||||
self.assertTrue(torch.allclose(y.grad, y.new_ones(y.shape)))
|
||||
self.assertClose(x.grad, x.new_ones(x.shape))
|
||||
self.assertClose(y.grad, y.new_ones(y.shape))
|
||||
|
||||
def test_torch_vectors(self):
|
||||
x = torch.tensor([0.2, 2.0])
|
||||
@@ -574,7 +574,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_vector_broadcast(self):
|
||||
x = torch.tensor([0.2, 2.0])
|
||||
@@ -598,7 +598,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_bad_broadcast(self):
|
||||
x = torch.tensor([0.2, 2.0, 20.0])
|
||||
@@ -629,7 +629,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_mixed_broadcast_grad(self):
|
||||
x = 0.2
|
||||
@@ -643,8 +643,8 @@ class TestTranslate(unittest.TestCase):
|
||||
z_grad = torch.tensor([1.0, 1.0])
|
||||
self.assertEqual(y.grad.shape, y_grad.shape)
|
||||
self.assertEqual(z.grad.shape, z_grad.shape)
|
||||
self.assertTrue(torch.allclose(y.grad, y_grad))
|
||||
self.assertTrue(torch.allclose(z.grad, z_grad))
|
||||
self.assertClose(y.grad, y_grad)
|
||||
self.assertClose(z.grad, z_grad)
|
||||
|
||||
def test_matrix(self):
|
||||
xyz = torch.tensor([[0.2, 0.3, 0.4], [2.0, 3.0, 4.0]])
|
||||
@@ -666,7 +666,7 @@ class TestTranslate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_matrix_extra_args(self):
|
||||
xyz = torch.tensor([[0.2, 0.3, 0.4], [2.0, 3.0, 4.0]])
|
||||
@@ -679,8 +679,8 @@ class TestTranslate(unittest.TestCase):
|
||||
im = t.inverse()._matrix
|
||||
im_2 = t._matrix.inverse()
|
||||
im_comp = t.get_matrix().inverse()
|
||||
self.assertTrue(torch.allclose(im, im_comp))
|
||||
self.assertTrue(torch.allclose(im, im_2))
|
||||
self.assertClose(im, im_comp, atol=1e-4)
|
||||
self.assertClose(im, im_2, atol=1e-4)
|
||||
|
||||
def test_get_item(self, batch_size=5):
|
||||
device = torch.device("cuda:0")
|
||||
@@ -692,7 +692,7 @@ class TestTranslate(unittest.TestCase):
|
||||
self.assertIsInstance(t3d_selected, Translate)
|
||||
|
||||
|
||||
class TestScale(unittest.TestCase):
|
||||
class TestScale(TestCaseMixin, unittest.TestCase):
|
||||
def test_single_python_scalar(self):
|
||||
t = Scale(0.1)
|
||||
matrix = torch.tensor(
|
||||
@@ -706,7 +706,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_single_torch_scalar(self):
|
||||
t = Scale(torch.tensor(0.1))
|
||||
@@ -721,7 +721,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_single_vector(self):
|
||||
t = Scale(torch.tensor([0.1, 0.2]))
|
||||
@@ -742,7 +742,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_single_matrix(self):
|
||||
xyz = torch.tensor([[0.1, 0.2, 0.3], [1.0, 2.0, 3.0]])
|
||||
@@ -764,7 +764,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_three_python_scalar(self):
|
||||
t = Scale(0.1, 0.2, 0.3)
|
||||
@@ -779,7 +779,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_three_torch_scalar(self):
|
||||
t = Scale(torch.tensor(0.1), torch.tensor(0.2), torch.tensor(0.3))
|
||||
@@ -794,7 +794,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_three_mixed_scalar(self):
|
||||
t = Scale(torch.tensor(0.1), 0.2, torch.tensor(0.3))
|
||||
@@ -809,7 +809,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_three_vector_broadcast(self):
|
||||
x = torch.tensor([0.1])
|
||||
@@ -833,7 +833,7 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_three_mixed_broadcast_grad(self):
|
||||
x = 0.1
|
||||
@@ -857,14 +857,14 @@ class TestScale(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
t._matrix.sum().backward()
|
||||
self.assertTrue(hasattr(y, "grad"))
|
||||
self.assertTrue(hasattr(z, "grad"))
|
||||
y_grad = torch.tensor(2.0)
|
||||
z_grad = torch.tensor([1.0, 1.0])
|
||||
self.assertTrue(torch.allclose(y.grad, y_grad))
|
||||
self.assertTrue(torch.allclose(z.grad, z_grad))
|
||||
self.assertClose(y.grad, y_grad)
|
||||
self.assertClose(z.grad, z_grad)
|
||||
|
||||
def test_inverse(self):
|
||||
x = torch.tensor([0.1])
|
||||
@@ -874,8 +874,8 @@ class TestScale(unittest.TestCase):
|
||||
im = t.inverse()._matrix
|
||||
im_2 = t._matrix.inverse()
|
||||
im_comp = t.get_matrix().inverse()
|
||||
self.assertTrue(torch.allclose(im, im_comp))
|
||||
self.assertTrue(torch.allclose(im, im_2))
|
||||
self.assertClose(im, im_comp)
|
||||
self.assertClose(im, im_2)
|
||||
|
||||
def test_get_item(self, batch_size=5):
|
||||
device = torch.device("cuda:0")
|
||||
@@ -887,7 +887,7 @@ class TestScale(unittest.TestCase):
|
||||
self.assertIsInstance(t3d_selected, Scale)
|
||||
|
||||
|
||||
class TestTransformBroadcast(unittest.TestCase):
|
||||
class TestTransformBroadcast(TestCaseMixin, unittest.TestCase):
|
||||
def test_broadcast_transform_points(self):
|
||||
t1 = Scale(0.1, 0.1, 0.1)
|
||||
N = 10
|
||||
@@ -965,10 +965,10 @@ class TestTransformBroadcast(unittest.TestCase):
|
||||
composed_mat = t1N2.get_matrix()
|
||||
self.assertTrue(composed_mat.shape == (N, 4, 4))
|
||||
expected_mat = torch.eye(3, dtype=torch.float32) * 0.3 * 0.2 * 0.1
|
||||
self.assertTrue(torch.allclose(composed_mat[0, :3, :3], expected_mat))
|
||||
self.assertClose(composed_mat[0, :3, :3], expected_mat)
|
||||
|
||||
|
||||
class TestRotate(unittest.TestCase):
|
||||
class TestRotate(TestCaseMixin, unittest.TestCase):
|
||||
def test_single_matrix(self):
|
||||
R = torch.eye(3)
|
||||
t = Rotate(R)
|
||||
@@ -983,7 +983,7 @@ class TestRotate(unittest.TestCase):
|
||||
],
|
||||
dtype=torch.float32,
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix))
|
||||
self.assertClose(t._matrix, matrix)
|
||||
|
||||
def test_invalid_dimensions(self):
|
||||
R = torch.eye(4)
|
||||
@@ -998,8 +998,8 @@ class TestRotate(unittest.TestCase):
|
||||
im = t.inverse()._matrix
|
||||
im_2 = t._matrix.inverse()
|
||||
im_comp = t.get_matrix().inverse()
|
||||
self.assertTrue(torch.allclose(im, im_comp, atol=1e-4))
|
||||
self.assertTrue(torch.allclose(im, im_2, atol=1e-4))
|
||||
self.assertClose(im, im_comp, atol=1e-4)
|
||||
self.assertClose(im, im_2, atol=1e-4)
|
||||
|
||||
def test_get_item(self, batch_size=5):
|
||||
device = torch.device("cuda:0")
|
||||
@@ -1011,7 +1011,7 @@ class TestRotate(unittest.TestCase):
|
||||
self.assertIsInstance(t3d_selected, Rotate)
|
||||
|
||||
|
||||
class TestRotateAxisAngle(unittest.TestCase):
|
||||
class TestRotateAxisAngle(TestCaseMixin, unittest.TestCase):
|
||||
def test_rotate_x_python_scalar(self):
|
||||
t = RotateAxisAngle(angle=90, axis="X")
|
||||
# fmt: off
|
||||
@@ -1030,10 +1030,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([0.0, 1.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 0.0, 1.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_x_torch_scalar(self):
|
||||
angle = torch.tensor(90.0)
|
||||
@@ -1054,10 +1052,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([0.0, 1.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 0.0, 1.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_x_torch_tensor(self):
|
||||
angle = torch.tensor([0, 45.0, 90.0]) # (N)
|
||||
@@ -1089,10 +1085,10 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
dtype=torch.float32,
|
||||
)
|
||||
# fmt: on
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
angle = angle
|
||||
t = RotateAxisAngle(angle=angle, axis="X")
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_y_python_scalar(self):
|
||||
t = RotateAxisAngle(angle=90, axis="Y")
|
||||
@@ -1112,10 +1108,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([1.0, 0.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 0.0, -1.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_y_torch_scalar(self):
|
||||
"""
|
||||
@@ -1141,10 +1135,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([1.0, 0.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 0.0, -1.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_y_torch_tensor(self):
|
||||
angle = torch.tensor([0, 45.0, 90.0])
|
||||
@@ -1176,7 +1168,7 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
dtype=torch.float32,
|
||||
)
|
||||
# fmt: on
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_z_python_scalar(self):
|
||||
t = RotateAxisAngle(angle=90, axis="Z")
|
||||
@@ -1196,10 +1188,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([1.0, 0.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 1.0, 0.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_z_torch_scalar(self):
|
||||
angle = torch.tensor(90.0)
|
||||
@@ -1220,10 +1210,8 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
points = torch.tensor([1.0, 0.0, 0.0])[None, None, :] # (1, 1, 3)
|
||||
transformed_points = t.transform_points(points)
|
||||
expected_points = torch.tensor([0.0, 1.0, 0.0])
|
||||
self.assertTrue(
|
||||
torch.allclose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
)
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(transformed_points.squeeze(), expected_points, atol=1e-7)
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_z_torch_tensor(self):
|
||||
angle = torch.tensor([0, 45.0, 90.0])
|
||||
@@ -1255,7 +1243,7 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
dtype=torch.float32,
|
||||
)
|
||||
# fmt: on
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_compose_x_y_z(self):
|
||||
angle = torch.tensor(90.0)
|
||||
@@ -1301,7 +1289,7 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
# order of transforms is t1 -> t2
|
||||
matrix = torch.matmul(matrix1, torch.matmul(matrix2, matrix3))
|
||||
composed_matrix = t.get_matrix()
|
||||
self.assertTrue(torch.allclose(composed_matrix, matrix, atol=1e-7))
|
||||
self.assertClose(composed_matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_rotate_angle_radians(self):
|
||||
t = RotateAxisAngle(angle=math.pi / 2, degrees=False, axis="Z")
|
||||
@@ -1318,7 +1306,7 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
dtype=torch.float32,
|
||||
)
|
||||
# fmt: on
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_lower_case_axis(self):
|
||||
t = RotateAxisAngle(angle=90.0, axis="z")
|
||||
@@ -1335,7 +1323,7 @@ class TestRotateAxisAngle(unittest.TestCase):
|
||||
dtype=torch.float32,
|
||||
)
|
||||
# fmt: on
|
||||
self.assertTrue(torch.allclose(t._matrix, matrix, atol=1e-7))
|
||||
self.assertClose(t._matrix, matrix, atol=1e-7)
|
||||
|
||||
def test_axis_fail(self):
|
||||
with self.assertRaises(ValueError):
|
||||
|
||||
Reference in New Issue
Block a user