diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..9054c02 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,19 @@ +FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04 + +ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none" + +# Optionally install the cmake for vcpkg +COPY ./reinstall-cmake.sh /tmp/ + +RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \ + chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ + fi \ + && rm -f /tmp/reinstall-cmake.sh + +# [Optional] Uncomment this section to install additional vcpkg ports. +# RUN su vscode -c "${VCPKG_ROOT}/vcpkg install " + +# [Optional] Uncomment this section to install additional packages. +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends \ + libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libgl1-mesa-dev mesa-utils diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..1dd8e6f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,35 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/cpp +{ + "name": "C++", + "build": { + "dockerfile": "Dockerfile" + }, + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}", + }, + "remoteEnv": { + "DOCKER_BUILDKIT": "0", + }, + "runArgs": [ + "--volume=/tmp/.X11-unix:/tmp/.X11-unix", + "--network", "host" + ], + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "gcc -v", + + // Configure tool-specific properties. + "customizations": { + "jetbrains": { + "backend": "CLion" + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "root" +} diff --git a/.devcontainer/reinstall-cmake.sh b/.devcontainer/reinstall-cmake.sh new file mode 100644 index 0000000..408b81d --- /dev/null +++ b/.devcontainer/reinstall-cmake.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- +# +set -e + +CMAKE_VERSION=${1:-"none"} + +if [ "${CMAKE_VERSION}" = "none" ]; then + echo "No CMake version specified, skipping CMake reinstallation" + exit 0 +fi + +# Cleanup temporary directory and associated files when exiting the script. +cleanup() { + EXIT_CODE=$? + set +e + if [[ -n "${TMP_DIR}" ]]; then + echo "Executing cleanup of tmp files" + rm -Rf "${TMP_DIR}" + fi + exit $EXIT_CODE +} +trap cleanup EXIT + + +echo "Installing CMake..." +apt-get -y purge --auto-remove cmake +mkdir -p /opt/cmake + +architecture=$(dpkg --print-architecture) +case "${architecture}" in + arm64) + ARCH=aarch64 ;; + amd64) + ARCH=x86_64 ;; + *) + echo "Unsupported architecture ${architecture}." + exit 1 + ;; +esac + +CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh" +CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt" +TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX) + +echo "${TMP_DIR}" +cd "${TMP_DIR}" + +curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O +curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O + +sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}" +sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license + +ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake +ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest diff --git a/.gitignore b/.gitignore index 1914940..763c84b 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,119 @@ CMakeSettings.json build/* bin/* *.DS_Store + +# ---> JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/ + +# CMake +cmake-build-*/ + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# ---> C++ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/src/cube.cpp b/src/cube.cpp index 233d42d..5c98dc6 100644 --- a/src/cube.cpp +++ b/src/cube.cpp @@ -8,15 +8,67 @@ void cube( Eigen::MatrixXd & NV, Eigen::MatrixXi & NF) { - //////////////////////////////////////////////////////////////////////////// - // Add your code here: - //////////////////////////////////////////////////////////////////////////// + // Construct default Blender cube. - ////Hint: - // V.resize(8,3); - // F.resize(6,4); - // UV.resize(14,2); - // UF.resize(6,4); - // NV.resize(6,3); - // NF.resize(6,4); + V.resize(8,3); + F.resize(6,4); +// for (int i = 0; i < 8; i++) { +// V(i,0) = 1 - (i&4) / 2; +// V(i,1) = 1 - 2 * (i&1); +// V(i,2) = -1 + 1 * (i&2); + +// V.row(i) = Eigen::RowVector3d(1 - (i&4) / 2, 1 - 2 * (i&1), -1 + 1 * (i&2)); + + /* Add Vertex to the faces it belongs to */ +// F(0 + (i&4) / 2, i % 4) = i; +// F(1 + 2 * (i&1), i / 2) = i; +// F(5 - (i&2) / 2, (i % 4) % 2 + (i / 4) * 2) = i; +// } + + V.row(0) = Eigen::RowVector3d( 1, 1, -1); + V.row(1) = Eigen::RowVector3d( 1, -1, -1); + V.row(2) = Eigen::RowVector3d( 1, 1, 1); + V.row(3) = Eigen::RowVector3d( 1, -1, 1); + V.row(4) = Eigen::RowVector3d(-1, 1, -1); + V.row(5) = Eigen::RowVector3d(-1, -1, -1); + V.row(6) = Eigen::RowVector3d(-1, 1, 1); + V.row(7) = Eigen::RowVector3d(-1, -1, 1); + + F.row(0) = Eigen::RowVector4i(1, 2, 4, 3); + F.row(1) = Eigen::RowVector4i(5, 1, 3, 7); + F.row(2) = Eigen::RowVector4i(6, 5, 7, 8); + F.row(3) = Eigen::RowVector4i(2, 6, 8, 4); + F.row(4) = Eigen::RowVector4i(3, 4, 8, 7); + F.row(5) = Eigen::RowVector4i(5, 6, 2, 1); + + NV.resize(6,3); + NV.row(0) = Eigen::RowVector3d(1, 0, 0); + NV.row(1) = Eigen::RowVector3d(0, 1, 0); + NV.row(2) = Eigen::RowVector3d(-1, 0, 0); + NV.row(3) = Eigen::RowVector3d(0, -1, 0); + NV.row(4) = Eigen::RowVector3d(0, 0, 1); + NV.row(5) = Eigen::RowVector3d(0, 0, -1); + + NF.resize(6,4); + for (int i = 1; i <= 6; i++) { + NF.row(i - 1) = Eigen::RowVector4i(i, i, i, i); + } + + UV.resize(14,2); + UV.row(0) = Eigen::RowVector2d(0.25, 0); + UV.row(1) = Eigen::RowVector2d(0.5, 0); + for (int i = 0; i < 5; i++) { + UV.row(2 + i) = Eigen::RowVector2d(0.25 * i, 0.25); + UV.row(7 + i) = Eigen::RowVector2d(0.25 * i, 0.5); + } + UV.row(12) = Eigen::RowVector2d(0.25, 0.75); + UV.row(13) = Eigen::RowVector2d(0.5, 0.75); + + UF.resize(6,4); + UF.row(0) = Eigen::RowVector4i(4, 5, 10, 9); + UF.row(1) = Eigen::RowVector4i(5, 6, 11, 10); + UF.row(2) = Eigen::RowVector4i(6, 7, 12, 11); + UF.row(3) = Eigen::RowVector4i(3, 4, 9, 8); + UF.row(4) = Eigen::RowVector4i(9, 10, 14, 13); + UF.row(5) = Eigen::RowVector4i(1, 2, 5, 4); } diff --git a/src/write_obj.cpp b/src/write_obj.cpp index 55c7f70..22c4208 100644 --- a/src/write_obj.cpp +++ b/src/write_obj.cpp @@ -16,5 +16,39 @@ bool write_obj( printf("ERROR in write_obj: F must have 3 or 4 columns"); exit(-1); } - return false; + + /* Write to file */ + std::ofstream out(filename.c_str()); + if (!out) { + printf("ERROR in write_obj: can't write to %s\n", filename.c_str()); + return false; + } + + /* Geometric vertices .*/ + for (int i = 0; i < V.rows(); i++) { + out << "v " << V(i, 0) << " " << V(i, 1) << " " << V(i, 2) << std::endl; + } + + /* Vertex normals */ + for (int i = 0; i < NV.rows(); i++) { + out << "vn " << NV(i, 0) << " " << NV(i, 1) << " " << NV(i, 2) << std::endl; + } + + /* Vertex texture coordinates */ + for (int i = 0; i < UV.rows(); i++) { + out << "vt " << UV(i, 0) << " " << UV(i, 1) << std::endl; + } + + /* Face elements */ + for (int i = 0; i < F.rows(); i++) { + out << "f"; + for (int j = 0; j < F.cols(); j++) { + out << " " << F(i, j) << "/" << UF(i, j) << "/" << NF(i, j); + } + out << std::endl; + } + + out.close(); + + return true; }