GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
//1// face.cpp2// Bistellar3//4// Created by Alexander Thumm on 07.10.11.5// Copyright 2011 -. All rights reserved.6//78#include "face.h"9#include <iostream>10#include <vector>11#include <string.h>12#include <stdlib.h>13#include "util.h"141516Face::Face() : _vertices(0), _dimension(-1)17{1819}2021Face::Face(const vertex_t * vertices, int dimension) : _vertices(0), _dimension(dimension)22{23if (_dimension < 0)24{25_dimension = -1;26}27else28{29_vertices = new vertex_t[dimension+1];30memcpy(_vertices, vertices, (dimension+1)*sizeof(vertex_t));31qsort(_vertices, dimension+1, sizeof(vertex_t), vertex_t_compare);32}33}3435Face::Face(const Face & cpy) : _vertices(0), _dimension(cpy._dimension)36{37if (cpy._vertices != 0)38{39_vertices = new vertex_t[cpy._dimension+1];40memcpy(_vertices, cpy._vertices, (cpy._dimension+1)*sizeof(vertex_t));41}42}4344Face::~Face()45{46if (_vertices != 0)47{48delete[] _vertices;49}50}5152Face & Face::operator=(const Face & cpy)53{54if (this == &cpy)55return *this;5657if (_vertices != 0)58{59delete[] _vertices;60_vertices = 0;61}62if (cpy._vertices != 0)63{64_vertices = new vertex_t[cpy._dimension+1];65memcpy(_vertices, cpy._vertices, (cpy._dimension+1)*sizeof(vertex_t));66}6768_dimension = cpy._dimension;6970return *this;71}7273bool Face::operator==(const Face & cmp) const74{75if (cmp._dimension != _dimension)76return false;7778if (_vertices == 0 && cmp._vertices == 0)79return true;80if (_vertices == 0 || cmp._vertices == 0)81return false;8283for (int i = 0; i < _dimension+1; i++)84{85if (vertex_t_compare(&cmp._vertices[i], &_vertices[i]) != 0)86return false;87}8889return true;90}9192bool Face::operator!=(const Face & cmp) const93{94return !(*this == cmp);95}9697int Face::dimension() const98{99return _dimension;100}101102const vertex_t & Face::vertex(unsigned int i) const103{104return _vertices[i];105}106107Face * Face::createBoundaryFace( unsigned int i ) const108{109if (i > _dimension || _vertices == 0)110return 0;111112if (_dimension == 0)113std::cout << "ERROR: tried to create boundary of a vertex." << std::endl;114115Face * boundaryFace = new Face;116boundaryFace->_dimension = _dimension-1;117boundaryFace->_vertices = new vertex_t[_dimension];118if (i != 0)119memcpy(&(boundaryFace->_vertices[0]), &(_vertices[0]), i*sizeof(vertex_t));120if (i != _dimension)121memcpy(&(boundaryFace->_vertices[i]), &(_vertices[i+1]), (_dimension-i)*sizeof(vertex_t));122123return boundaryFace;124}125126bool Face::isSubfaceOf(const Face & face) const127{128if (face._dimension < _dimension || _dimension == -1)129return false;130131/*int j = 0;132for (int i = 0; i < _dimension+1; i++)133{134while (j < face._dimension+1 && vertex_t_compare(&(_vertices[i]), &(face._vertices[j])) != 0)135j++;136}137138if (j > face._dimension)139return false;*/140141int i = 0;142int j = 0;143while (i < _dimension+1 && j < face._dimension+1)144{145const int comparison = vertex_t_compare(&(_vertices[i]), &(face._vertices[j]));146if (comparison == 0)147{148i++;149}150else if (comparison < 0)151{152return false;153}154j++;155}156157if (i < _dimension+1)158return false;159160return true;161}162163// serialization methods164std::ostream & operator<< (std::ostream & os, const Face & face)165{166if (face._vertices == 0)167{168os<<"[]";169}170else171{172list_print(os, &(face._vertices[0]), &(face._vertices[face._dimension+1]));173}174175return os;176}177std::istream & operator>> (std::istream & is, Face & face)178{179std::vector< vertex_t > vertices;180list_read(is, vertices);181182if (vertices.empty())183{184face = Face();185}186else187{188face = Face(&vertices[0], static_cast<int>(vertices.size() - 1));189}190191return is;192}193194Face Face::linkFace(const Face & face, const face_list_t & linkFacets)195{196size_t size = 0;197for (face_list_t::const_iterator it = linkFacets.begin(); it != linkFacets.end(); it++)198{199size += it->_dimension+1;200}201202vertex_t * linkVertices = new vertex_t[size];203204size_t pos = 0;205for (face_list_t::const_iterator it = linkFacets.begin(); it != linkFacets.end(); it++)206{207memcpy(&(linkVertices[pos]), it->_vertices, (it->_dimension+1)*sizeof(vertex_t));208pos += (it->_dimension+1);209}210211qsort(linkVertices, size, sizeof(vertex_t), &vertex_t_compare);212size = remove_duplicates(linkVertices, size, sizeof(vertex_t), &vertex_t_compare);213size = remove_from_set(linkVertices, size, face._vertices, face._dimension+1, sizeof(vertex_t), &vertex_t_compare);214215Face linkFace(linkVertices, static_cast< int >(size)-1);216delete[] linkVertices;217218return linkFace;219}220221Face Face::unite(const Face & face1, const Face & face2)222{223if (face1.dimension() == -1)224return face2;225if (face2.dimension() == -1)226return face1;227228vertex_t * vertices = new vertex_t[face1._dimension + face2._dimension + 2];229memcpy(vertices, face1._vertices, (face1._dimension+1)*sizeof(vertex_t));230memcpy(&(vertices[face1._dimension+1]), face2._vertices, (face2._dimension+1)*sizeof(vertex_t));231232qsort(vertices, face1._dimension + face2._dimension + 2, sizeof(vertex_t), &vertex_t_compare);233size_t size = remove_duplicates(vertices, face1._dimension + face2._dimension + 2, sizeof(vertex_t), &vertex_t_compare);234235Face unionFace(vertices, static_cast< int >(size)-1);236delete[] vertices;237238return unionFace;239}240241242void addBoundaryfacesOfFace(const Face & face, face_list_t & listOfBoundaryfaces)243{244vertex_t * boundaryfaceVertices = (face.dimension() < 1 ? 0 : new vertex_t[face.dimension()]);245246for (unsigned int i = 0; i < face.dimension(); i++)247boundaryfaceVertices[i] = face.vertex(i+1);248249if (face.dimension() > 0)250listOfBoundaryfaces.push_back(Face(boundaryfaceVertices, face.dimension()-1));251for (unsigned int i = 0; i < face.dimension(); i++)252{253boundaryfaceVertices[i] = face.vertex(i);254listOfBoundaryfaces.push_back(Face(boundaryfaceVertices, face.dimension()-1));255}256257if (boundaryfaceVertices != 0)258delete[] boundaryfaceVertices;259}260261void incrementBitmask(std::vector< bool > & bitmask);262263void addSubfacesOfFace(const Face & face, face_list_t & listOfSubfaces)264{265vertex_t * subfaceVertices = (face.dimension() < 1 ? 0 : new vertex_t[face.dimension()]);266267std::vector< bool > bitmask(face.dimension()+1, false);268for (unsigned long long int i = 0; i < (face.dimension() < 0 ? 0 : (1<<(face.dimension()+1))-2); i++)269{270incrementBitmask(bitmask);271272unsigned int subfaceSize = 0;273std::vector< bool >::const_iterator it;274unsigned int index;275276for (it = bitmask.begin(), index = 0; it != bitmask.end(); it++, index++)277{278if (*it)279{280subfaceVertices[subfaceSize] = face.vertex(index);281subfaceSize++;282}283}284285listOfSubfaces.push_back(Face(subfaceVertices, subfaceSize-1));286}287288if (subfaceVertices != 0)289delete[] subfaceVertices;290}291292void incrementBitmask(std::vector< bool > & bitmask)293{294std::vector< bool >::iterator it = bitmask.begin();295while (it != bitmask.end())296{297if ((*it = !*it))298break;299it++;300}301}302303