vcglib 说明(转载)

2023-11-14

先来看看 VCGlib 能做什么

  • 最基本的,它提供 Mesh(triangular mesh,tetrahedralmesh,三角网格或四面体网格)数据结构的定义,该数据结构支持对 Mesh数据的快速访问(拓扑信息、空间查询等)以及高效执行网格上算法;
  • 在 Mesh数据结构基础上,实现大量高效的网格算法,如网格修补、平滑、变形、曲率计算、细分、泊松盘采样、等值面计算等;
  • IO 支持,读写 PLY、OBJ、STL、3DS、OFF、DXF 等格式网格文件;
  • UI 支持,如 OpenGL 网格显示,Trackball 交互等。

VCGlib 的文档很简陋, 在线文档 并不是很全,可以自己用 Doxygen从下载的源代码生成 html API 文档 ,为此只需要(Windows 用户):

  1. 安装 Doxygen (Doxywizard) 和 Graphviz,将“Graphviz安装目录\Graphviz2.36\bin”添加到环境变量Path;
  2. 将本博客所附程序中的 “OpenGL Shadow\_Libs\vcglib\docs\doxyfile-all”文件拷贝到下载的 VCGlib 文件夹下的 “vcglib\docs\Doxygen” 下,这个文件是我配置好的 Doxygen配置文件;
  3. 用 Doxywizard 打开上一步拷贝的文件,点击“Run” 选项卡下的 “Run doxygen” 按钮,生成的 API 文档将位于“vcglib\docs\Doxygen\html-all” 下(html-all 文件夹将有 129M 大小)。

VCGlib 是纯头文件库,要 安装 只需将下载 VCGlib库目录添加到程序的头文件包含路径(有些IO函数如读写PLY需要包含相应.cpp文件)。

后面按照如下步骤讲解:
  1. 定义 Mesh 类型;
  2. 访问及指定 Mesh 的顶点、三角形(对三角网格,如果是四面体网格则是四面体,这里默认只讲三角网格)等数据;
  3. IO,读写 PLY、OBJ 等网格文件;
  4. 构造网格的拓扑信息,如顶点或三角形面法向量、三角形相邻三角形、边连接的三角形等信息;
  5. 网格处理,如法向量平滑、网格修补等。

定义 Mesh 类型的典型代码如下(API 文档主页 Basic Concepts,在线版 ):

#include "vcg/complex/complex.h"
// 类型声明
class MyVertex;class MyEdge;
class MyFace;
typedef vcg::UsedTypes<</FONT>
  vcg::Use::AsVertexType,
  vcg::Use  ::AsEdgeType,
  vcg::Use  ::AsFaceType >
MyUsedTypes;
// 顶点类型
class MyVertex : public vcg::Vertex<</FONT>MyUsedTypes,
  vcg::vertex::Coord3f,
  vcg::vertex::Normal3f,
  vcg::vertex::BitFlags > { };
// 边类型
class MyEdge : public vcg::Edge<</FONT>MyUsedTypes,
 vcg::edge::VertexRef,
 vcg::edge::EFAdj,
 vcg::edge::BitFlags > { };
// 面类型,三角形 class MyFace : public vcg::Face<</FONT>MyUsedTypes,  vcg::face::VertexRef,  vcg::face::Normal3f,  vcg::face::FFAdj,  vcg::face::BitFlags > { }; // 网格类型 typedef vcg::tri::TriMesh<</FONT>  std::vector,  std::vector,  std::vector > GLMesh;

抛开 MyUseTypes 不看,上面代码定义的网格类型为:

  • 网格包含属性:顶点、边、三角形数组(std::vector<>);
  • 每个顶点包含属性:空间坐标(3个float表示)、顶点法向量、标志位;
  • 每个边包含属性:顶点指针(指向该边的两个顶点)、边-面邻接信息、标志位;
  • 每个三角形面包含属性:顶点指针(指向该三角形的三个顶点)、面法向量、面-面邻接信息、标志位。

VCGlib 使用 Reference 数据结构,对每个边、面用指针记录其顶点、邻接面等信息,其他网格数据结构见wikipedia Polygon Mesh 条目

为了做到足够通用, VCGlib 使用了C++ templatemetaprogramming(模板元编程)方法 。上面代码中的MyVertex、MyEdge、MyFace、GLMesh等类型包含哪些属性(模板参数)、属性的顺序(模板参数顺序)都是可以根据需要随意指定的(当然,必须包含足够的属性以执行相应网格算法),一般来说,最好使顶点、边、面包含标志位属性(BitFlags),BitFlags指示该顶点、边、面是否可写、可读、已删除(为了效率,例如,删除顶点操作可能并不立即删除顶点数据,而仅仅打个标志位,待所有操作完成再更新顶点数据)等。不去深入VCGlib元编程机理(说实话我还没弄清楚),可选个数模板参数是通过默认模板参数实现的,vcg::Vertex/Edge/Face<>将继承其模板参数。

下面列举所有可选的模板参数:
  • 网格 vcg::tri::TriMesh<>最多可有四个参数:顶点容器、边容器、面容器、半边容器(vcg::HEdge<>);
  • 顶点 vcg::Vertex<>  可以包含的属性有:坐标、法向量、颜色、纹理坐标、标志位、网格质量(网格在该点出优劣评价指标)、曲率、半径、顶点-边邻接信息、顶点-面邻接信息、顶点-半边邻接信息,等(API文档 Modules 选项卡 Vertex Components, 在线版 );
  • 边 vcg::Edge<>  可以包含的属性有:顶点指针、颜色、标志位、网格质量、边-顶点邻接信息、边-边邻接信息、边-面邻接信息、边-半边邻接信息,等(API文档 Modules 选项卡 Edge Components, 在线版 );
  • 面 vcg::Face<>  可以包含的属性有:顶点指针、法向量、颜色、标志位、网格质量、顶点-面邻接信息、面-边邻接信息、面-面邻接信息,等(API 文档Modules 选项卡 Face Components, 在线版 )。
访问 Mesh 数据示例代码如下:
  // load mesh ...
int i=0, j=0;
// 见 vcg::tri::TriMesh<> -------------------------------------------------------------
mesh.VN(); mesh.EN(); mesh.FN(); // 顶点、边、面个数,可能小于 vs/es/fs.size()
  // 因为有些元素被删除时仅仅打了标志位而并未删除存储数据
std::vector& vs = mesh.vert; // 顶点数组
std::vector&   es = mesh.edge; // 边数组
std::vector&   fs = mesh.face; // 面数组
// 见 vcg::Vertex<> 及其 模板参数 -------------------------------------------------------
GLMesh::VertexType& v = mesh.vert[i]; // 第 i 个顶点,假设 v.isD()==false,即未标志为已删除
v.P().Z(); v.P().V(j);    // 顶点坐标,其xyz分量
v.N().X(); // 顶点法向,其x分量
// 见 vcg::Edge<> 及其 模板参数 ---------------------------------------------------------
GLMesh::EdgeType& e = mesh.edge[i]; // 第 i 个边,假设 e.isD()==false
GLMesh::VertexType* pve = e.V(j);   // j=0,1,边的两个端点顶点的指针
GLMesh::FaceType*   pfa = e.EFp();  // 边-面邻接信息,该边连接的第一个面
// 见 vcg::Face<> 及其 模板参数 ---------------------------------------------------------
GLMesh::FaceType& f = mesh.face[i]; // 第 i 个面(三角形),假设 f.isD()==false
GLMesh::VertexType* pvf = f.V(j);   // j=0,1,2,三角形面的三个顶点的指针
f.N(); // 面的法向量
GLMesh::FaceType* pfb = f.FFp(j); // 面-面邻接信息,j=0,1,2,面 f 通过其第j个边连接的第一个面
// 可以通过返回的引用(左值)修改数据,但不要随便修改,见下文 ------------------------------------
v.P().Y() += 3.2f;
e.V(j) = &v;
f.V(j) = &v;
// 遍历所有顶点、边、面需要跳过标记为已删除的元素 ---------------------------------------------
for(size_t i=0; ii){
    if(vs[i].IsD()) continue;
    // do some thing for each vertex vs[i] ...
}
    // 除非已经删除了所有标记为已删除元素的存储数据,比如:
vcg::tri::Allocator::CompactVertexVector(mesh);
vcg::tri::Allocator::CompactEdgeVector(mesh);
vcg::tri::Allocator::CompactFaceVector(mesh);
for(size_t i=0; ii){
    // do some thing for each face fs[i] ...
}

填充(Fill)Mesh 数据的示例代码如下 (API 文档主页 Creating and destroyingelements, 在线版 ,代码摘自那里):

// VCGlib Reference 数据结构,依赖于指针,直接操作顶点、边、面数组 mesh.vert/edge/face 可能
// 产生 std::vector<> 存储重新分配,此时,相关指针将失效,vcg::tri::Allocator<> 处理这些问题
GLMesh m;
GLMesh::VertexIterator vi = vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddVertices(m, 3);
GLMesh::FaceIterator fi = vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddFaces(m, 1);
GLMesh::VertexPointer ivp[4];
ivp[0]=&*vi; vi->P()=GLMesh::CoordType(0.0f,0.0f,0.0f); ++vi;
ivp[1]=&*vi; vi->P()=GLMesh::CoordType(1.0f,0.0f,0.0f); ++vi;
ivp[2]=&*vi; vi->P()=GLMesh::CoordType(0.0f,1.0f,0.0f); ++vi;
fi->V(0)=ivp[0]; fi->V(1)=ivp[1]; fi->V(2)=ivp[2];
// Alternative, more compact, method for adding a single vertex
ivp[3]= &*vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddVertex(m,GLMesh::CoordType(1.0f,1.0f,0.0f));
// Alternative, method for adding a single face (once you have the vertex pointers)
vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddFace(m, ivp[1],ivp[0],ivp[3]);

// 同理,如果自己保存了顶点等数据指针,需要在修改顶点、边、面数组后更新该指针 --------------------
// a potentially dangerous pointer to a mesh element
GLMesh::FacePointer fp = &m.face[0];
vcg::tri::Allocator<<SPAN class=title>GLMesh>::PointerUpdater<<SPAN class=title>GLMesh::FacePointer> pu;
// now the fp pointer could be no more valid due to eventual re-allocation of the m.face
vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddVertices(m,3);
vcg::tri::Allocator<<SPAN class=title>GLMesh>::AddFaces(m,1,pu);
// check if an update of the pointer is needed and do it.
if(pu.NeedUpdate()) pu.Update(fp);

// 删除元素的代码如下 --------------------------------------------------------------------
vcg::tri::Allocator<<SPAN class=title>GLMesh>::DeleteFace(m,m.face[0]);

// 拷贝网格的代码如下,GLMesh 没有拷贝构造函数,也没有 operator= -----------------------------
GLMesh m2;
vcg::tri::Append<<SPAN class=title>GLMesh,GLMesh>::MeshCopy(m2,m);

IO,读写网格文件示例代码如下(API 文档主页 Loading and savingmeshes, 在线版 ):

// Mesh 文件一般至少包含顶点数组信息,还可以包含连接信息(三角形)、顶点法向量、顶点颜色、面颜色、
// 面法向量、纹理坐标等等属性,用 mask 的二进制位来标记或控制读取或写入了 Mesh 文件的哪些属性
// 见 vcg::tri::io::Mask,读取 PLY 需要包含文件 "vcglib/wrap/ply/plylib.cpp"(见这里
// 头文件包含:#include "wrap/io_trimesh/import.h" #include "wrap/io_trimesh/export.h"
GLMesh m; int mask;
// 读取 PLY 文件,并检查返回值,参数 mask 为可选,mask 是返回参数:读入了哪些属性
if( vcg::tri::io::ImporterPLY::Open(m, "file_to_open.ply", mask)
  != vcg::ply::E_NOERROR ) {
  std::cout <</FONT>< "Load PLY file ERROR\n";
}
 // some modification to m and mask ...
// 保存 PLY 文件,mask 是输入参数,控制 m 的哪些属性被写入到文件
vcg::tri::io::ExporterPLY<<SPAN class=attribute>GLMesh>::Save(m, "file_to_save.ply", mask);
// 读取或写入 OBJ 文件的代码,mask 作用同上
if( vcg::tri::io::ImporterOBJ<<SPAN class=title>GLMesh>::Open(m, "file_to_open.obj", mask)
  != vcg::tri::io::ImporterOBJ<<SPAN class=title>GLMesh>::E_NOERROR ) {
    std::cout <<SPAN class=title><</SPAN> "Load OBJ file ERROR\n";
}
  // some modification to m and mask ...
vcg::tri::io::ExporterOBJ<<SPAN class=attribute>GLMesh>::Save(m, "file_to_save.obj", mask);
// 读取、写入网格文件,将根据文件扩展名自动匹配文件格式 ---------------------------------------
int oerr = vcg::tri::io::Importer<<SPAN class=title>GLMesh>::Open(m, "file_to_open.off", mask);
if( oerr != 0 ){
  std::cout <<SPAN class=title><</SPAN> "Load mesh file ERROR: "
    << vcg::tri::io::Importer<<SPAN class=attribute>GLMesh>::ErrorMsg(oerr) <<SPAN class=title><</SPAN> '\n';
}
  // some modification to m and mask ...
int serr = vcg::tri::io::Exporter<<SPAN class=attribute>GLMesh>::Save(m, "file_to_save.3ds", mask);
if( serr != 0 ){
  std::cout <<SPAN class=title><</SPAN> "Save mesh file ERROR: "
    << vcg::tri::io::Exporter<<SPAN class=attribute>GLMesh>::ErrorMsg(oerr) <<SPAN class=title><</SPAN> '\n';
}

构造网格拓扑信息示例代码如下 (API 文档主页 Adjacency andTopology, 在线版 ):

  // load mesh ...
vcg::tri::UpdateNormal<<SPAN class=title>GLMesh>::PerFaceNormalized(mesh); // 计算顶点法向量,并单位化
vcg::tri::UpdateNormal<<SPAN class=title>GLMesh>::PerVertexNormalized(mesh); // 计算面法向量,并单位化
vcg::tri::UpdateTopology<<SPAN class=title>GLMesh>::FaceFace(mesh); // 计算面-面邻接信息
vcg::tri::UpdateTopology<<SPAN class=title>GLMesh>::AllocateEdge(mesh); // 计算边-面邻接信息,需要面-面信息
vcg::Matrix44f mat(&glm::translate(glm::vec3(1,2,3))[0][0]);
vcg::tri::UpdatePosition<<SPAN class=title>GLMesh>::Matrix(mesh, mat, true); // 更新顶点位置,并更新法向量
// 在调用 UpdateTopology<>::FaceFace() 和 UpdateTopology<>::AllocateEdge() 后就构造了边到面
// 的信息,对于 manifold 网格,每个边必连接两个三角形面,下面代码对边 i 查找其连接的面 fa 和 fb
int i=0; GLMesh::EdgeType& e = mesh.edge[i];
GLMesh::FaceType* fa = e.EFp();
GLMesh::FaceType* fb = fa->FFp(e.EFi());

在准备这篇博客之初,研究 VCGlib 时,发现了 VCGlib 的一个 BUG,已经报告给开发者并得到确认( 见这里 ,看看时间,发现这篇博客因为一些原因拖了20多天...)。

网格处理示例代码如下:
vcg::tri::Clean<<SPAN class=title>GLMesh>::RemoveDuplicateVertex(mesh); // 去除重合的顶点
vcg::tri::Smooth<<SPAN class=title>GLMesh>::VertexNormalLaplacian(mesh, 5); // 平滑顶点法向量
float maxSizeHole = 2.0f; // fill 所有直径小于 maxSizeHole 的洞
vcg::tri::Hole<<SPAN class=title>GLMesh>::EarCuttingIntersectionFill
    <<SPAN class=title>vcg::tri::SelfIntersectionEar>>(mesh, maxSizeHole, false);
进一步学习的资源:
  • 下载的 VCGlib 源代码 “vcglib\apps\sample” 下的官方示例代码;
  • 源代码,结合 API 文档;
  • 基于 VCGlib 的软件 MeshLab ,可以用于网格文件处理。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vcglib 说明(转载) 的相关文章

  • SmartAndroid之SmartJump,告别onActivityResult

    SmartJump 需求 应用场景 实现思路 代码 调用示例 后记 需求 在跳转到另一个Activity后 通过回调直接获取到数据 应用场景 普通的activity跳转 回调获取数据可以使逻辑更清晰 第三方库中activity数据回调可以让
  • 实战案列:AntiDebug

    往期推荐 self debugging反调试 轮循检测技术 进程名称检测 Java层反调试 Anti Debug主要是通过各种函数去确定当前进程是否处于被调试的状态 一 IDA里面静态分析so文件 1 将文件拖入jdax gui中 进行静态
  • PLSQL字体设置常见问题

    PLSQL字体设置常见问题 从网络资源下载的PLSQL 字体默认的大小不太适合大屏幕的电脑 因为看起来字体很小 我们可打开PLSQL来设置字体的大小以及其他常规设置 一 字体太小 操作流程 菜单栏的Tools gt Preferences
  • 静态多态和动态多态

    多态 静态多态和动态多态 多态的实现主要分为静态多态和动态多态 静态多态主要是重载和模板 在编译的时候就已经确定 动态多态是用虚函数机制实现的 在运行期间动态绑定 举个例子 一个父类类型的指针指向一个子类对象时候 使用父类的指针去调用子类中
  • vue学习 十二 vue文件目录知晓 or 组件嵌套

    说明 我使用的是HBuilder 软件能用就可以了 查看顺序是 index html 入口文件 gt main js gt App vue 模板文件 可以看出能显示出欢迎页面 还有那个大V都在这里可以看到 gt components 自定义
  • Redis DEL删除命令是否会导致阻塞

    DEL命令是存在阻塞的可能性的 1 使用DEL命令删除key DEL keya keyb keyc 2 根据删除的key的数量和类型 操作的时间复杂度不同 删除N个key key中的数量为M则时间复杂度是O N M 删除一个字符串的key则
  • 类中有引用需要注意——非静态的引用成员错误提示,不能使用默认的赋值运算符

    我们知道 当我们我们没有定义赋值操作符时 编译器会生成一个默认的赋值操作符执行浅拷贝 就像默认构造函数一样是编译器默认生成的 而如果勒种有引用就需要注意一个大大的误区 我们知道引用在定义的时候就需要初始化 指定这个引用变量是哪个变量的别名
  • C常用标准库及函数

    常用头文件 stdio h stdlib h ctype h string h math h system h 1 stdio库 主要功能是输入输出操作 包括文件输入输出 标准输入输出 输出函数 int puts const char st
  • Method的invoke方法初步了解

    Java调试过程中 我们有时候会需要对JVM运行过程中哪出了问题进行调试 先从最基础的了解 我们都知道Java框架中方法的调用基本上都是通过反射机制来实施的 具体流程如下 1 方法的调用先检查AccessibleObject的overrid
  • IT项目管理-HW6

    1 a b c 最后一条为该项目的关键路径 长度为15天 d 完成该项目所需的最短时间可能是10天 3 根据 1 中介绍 看板在项目流程中载体的分类为两种 一种是实体看板 一种是互联网看板 实体看板是敏捷开发团队中使用的最多 最直接的一种看
  • 脉冲的三种形式

    脉冲信号可以分为AB相脉冲 脉冲 方向 CW CCW脉冲 这三种信号格式 在十几年前或者还有明显的相对优缺点和适用场合 现在就已经无所谓了 即使在使用上还是有所区分 也基本上是由于历史习惯 1 A B信号 位置传感器最喜欢的格式 因为 早期
  • 修改远程桌面端口bat批处理(windows)

    新建批处理 将以下内容复制进去即可 修改成功后会自动重启 echo off color f0 echo 修改远程桌面3389端口 支持Windows 2003 2008 2008R2 2012 2012R2 7 8 10 echo 自动添加
  • springboot 集成 elasticsearch(maven项目)

    1 搭建springboot项目 能跑起来 具体百度 我的springboot版本 1 5 9 RELEASE 2 本机或者服务器安装elasticsearch并启动服务成功 我本地Windows安装的elasticsearch版本6 1
  • geo算法了解学习以及选择

    需求 通过坐标了解到距离最近的桩号 建筑 景点 Mysql Sql语句 SELECT id ST Distance Sphere POINT item longitude item latitude POINT longitude lati
  • Postman第七篇:其他好用的功能及工具

    其他好用的功能及工具 分组 Collection 在刚开始一个项目时 为了后续便于组织和管理 把同属该项目的多个 API 放在一组里 所以要先去新建一个 Collection New gt Collection 使用了段时间后 建了多个分组
  • 如何创建一个自己的sphinx文档网站

    文章目录 前言 一 操作步骤 1 安装anaconda 2 启动python3 8环境 3 安装Sphinx 4 创建文件夹 5 初始化环境 6 编译 7 文件夹搭查看 8 搭建nginx查看 8 更换主题 9 错误修复 10 这里提供两个
  • IDEA学习记录19--sql注入与Statement预编译

    1 sql注入 package net xdclass web dao import java sql Connection import java sql DriverManager import java sql ResultSet i
  • 从FindBugs中学Java【一】

    2019独角兽企业重金招聘Python工程师标准 gt gt gt findbug 这里 中文列表 http svn codehaus org sonar plugins tags sonar l10n zh plugin 1 1 src

随机推荐

  • forwardRef 的详解及使用

    一 介绍 React forwardRef 会创建一个React组件 这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中 这种技术并不常见 但在以下两种场景中特别有用 转发 refs 到 DOM 组件 在高阶组件中转发 re
  • vue 一直发送请求websocket

    vue项目运行时一直请求websocket 导致控制台 接口大量报错无法查看控制台输出内容以及接口返回值 解决办法 打开 node modules sockjs client dist sockjs js 文件将 self xhr send
  • easyexcel poi 指定行指定列设置样式

    easyexcel poi 指定行指定列设置样式 1 给指定行指定列设置字体及居中 2 给指定行指定列设置边框 1 给指定行指定列设置字体及居中 给指定行指定列设置字体及居中 param workbook param rowIndex 第几
  • 【小沐学CAD】虚拟仿真开发工具:GL Studio

    文章目录 1 简介 2 软件功能 3 应用行业 3 1 航空 3 2 汽车 3 3 防御 3 4 工业 3 5 电力与能源 3 6 医疗 3 7 空间 3 8 科技 结语 1 简介 https disti com gl studio htt
  • 数据结构之算法复杂度篇

    要努力 但是不要急 繁花锦簇 硕果累累都需要过程 目录 前言 1 什么是数据结构 2 什么是算法 3 算法的复杂度 1 概念 2 时间复杂度 3 空间复杂度 4 常见的复杂度对比 4 复杂度的oj练习 5 总结 前言 在程序段运行的时候 我
  • 将h5封装为微信小程序

    1 要求网站域名必须为https 2 登录微信公众号好注册一个小程序账号 3 打开威胁你开发者工具进行创建 4 打开app json文件 pages项只保留 pages index index 这一行 5 打开 pages index in
  • 【千律】C++基础:类定义和类实现的分离

    类定义就是指定义类名 是 h文件 类实现是指对类定义的具体实现 是 cpp文件 下面是Student h中的内容 pragma once include
  • frc机器人比赛主题_参加了十几场机器人竞赛后,我才敢告诉你:怎样做到不“踩坑”?...

    在决定参加比赛之前 先问自己为什么 为什么要先聊这一点 因为这个问题会决定你的很多选择 很多家长会先去看那个 果 比如 比赛获奖有没有用 这个比赛含金量如何 但是这个 因 是每个家长要先问自己的 你是不是认同机器人竞赛是对孩子综合能力的提升
  • 2000端口号的坑

    这两天对接某游戏的充值接口的时候碰到一个恶心的问题 公司机器和服务器请求游戏方2000端口号的时候 死活获取不到返回No Response 但是同一个请求串外网环境都是正常的 经多次和游戏方你来我往之后发现 2000端口默认是sccp协议
  • 2W字长文吐血整理 Docker&云原生

    Docker 和 云原生 一 概念介绍 1 1 Docker Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中 然后发布到任何流行的 Linux或Windows操作系统的机器上 也可以实现虚拟
  • React 应用的 Nginx 缓存控制

    典型 React 应用面临的缓存问题 可通过 Nginx 配置进行解决 通用部署 构建应用后 只需使用 Nginx 指向静态文件即可 server listen 80 root PATH TO APP build try files uri
  • 爬虫碎碎念

    20230304 非专业人士 简单记录自己的需求和思考 0 引言 平时看到一些网站的照片什么的 有那种批量下载的需求 当然有些也是视频网站的图片介绍什么的 也即是说 我需要把这些网站的照片批量下载下来 以前的时候 写过简单的爬虫 因为需求比
  • Docker——搭建ELK

    安装Elasticsearch 1 拉取镜像 docker box home box docker pull elasticsearch 7 14 2 2 在宿主机准备配置文件 创建目录 docker box mkdir p server0
  • 资源list:Github上关于大数据的开源项目、论文等合集

    Awesome Big Data A curated list of awesome big data frameworks resources and other awesomeness Inspired byawesome php aw
  • 注释转换(C->C++)

    转换原理图解 基于上图原理 可以写出代码 主函数 define CRT SECURE NO WARNINGS 1 include
  • Jenkins从配置到实战(二) - Jenkins的Master-Slave分布式构建

    前言 Jenkins的Master Slave分布式构建 就是通过将构建过程分配到从属Slave节点上 从而减轻Master节点的压力 而且可以同时构建多个 有点类似负载均衡的概念 简单理解就是 将Jenkins服务器上的构建任务分配到其他
  • 数据采集专家----4通道AD采集子卡推荐

    FMC136是一款4通道250MHz采样率16位AD采集FMC子卡 符合VITA57规范 可以作为一个理想的IO模块耦合至FPGA前端 4通道AD通过高带宽的FMC连接器 HPC 连接至FPGA从而大大降低了系统信号延迟 该板卡支持板上可编
  • Unity_Shader高级篇_16_Unity Shader入门精要_减少计算复杂度

    16 8 减少计算复杂度 16 8 1 Shader的LOD技术 和16 5 2提到的模型的LOD技术类似 Shader的LOD技术可以控制使用的Shader等级 它的原理是 只有Shader的LOD值小于某个设定的值 这个Shader才会
  • vue rsa对密码加密(jsencrypt)

    首先用npm命令下载jsencrypt npm install jsencrypt dep 在vue文件中引入jsencrypt import JSEncrypt from jsencrypt 对password加密 this encryp
  • vcglib 说明(转载)

    先来看看 VCGlib 能做什么 最基本的 它提供 Mesh triangular mesh tetrahedralmesh 三角网格或四面体网格 数据结构的定义 该数据结构支持对 Mesh数据的快速访问 拓扑信息 空间查询等 以及高效执行