티클러 2026. 5. 21. 23:01

잠시 테스트삼아 만들어본 netgen 예제.. 

#include <iostream>
#include <fstream>
#include <vector>

namespace nglib {
#include <nglib.h>
#include <nglib_occ.h>
}

bool SaveMeshAsOBJ(nglib::Ng_Mesh* mesh, const std::string& filepath) {
	std::ofstream obj_file(filepath);
	if (!obj_file.is_open()) {
		std::cerr << "에러: OBJ 파일을 생성할 수 없습니다: " << filepath << std::endl;
		return false;
	}

	obj_file << "# Generated by Netgen and Custom C++ Exporter\n";
	obj_file << "# Object Name: QuadDominatedMesh\n\n";

	int num_points = nglib::Ng_GetNP(mesh);
	for (int i = 1; i <= num_points; ++i) {
		double pt[3];
		nglib::Ng_GetPoint(mesh, i, pt);
		obj_file << "v " << pt[0] << " " << pt[1] << " " << pt[2] << "\n";
	}
	obj_file << "\n";

	int num_elements = nglib::Ng_GetNSE(mesh);
	for (int i = 1; i <= num_elements; ++i) {
		int pi[4]; 
		int mat;
		nglib::Ng_Surface_Element_Type et = nglib::Ng_GetElement_2D(mesh, i, pi, &mat);

		if (et == nglib::NG_QUAD) {
			obj_file << "f " << pi[0] << " " << pi[1] << " " << pi[2] << " " << pi[3] << "\n";
		} 
		else if (et == nglib::NG_TRIG) {
			obj_file << "f " << pi[0] << " " << pi[1] << " " << pi[2] << "\n";
		}
	}

	obj_file.close();
	return true;
}

int main() {
	using namespace nglib;

	// Netgen 및 OCC 커널 초기화
	Ng_Init();

	// STEP 지오메트리 파서 생성 및 로드
	const char* filename = "model.step"; 

	Ng_OCC_Geometry* occ_geo = Ng_OCC_Load_STEP(filename);
	if (!occ_geo) {
		std::cerr << "에러: STEP 파일을 불러오지 못했습니다." << std::endl;
		Ng_Exit();
		return 1;
	}
	std::cout << " STEP 파일 로드 성공" << std::endl;

	// 메시 객체 및 생성 조건 설정
	Ng_Mesh* mesh = Ng_NewMesh();
	Ng_Meshing_Parameters mp;

	mp.elementspercurve = 0.0;
	mp.uselocalh = 1;
	mp.maxh = 1;            	// 요소의 최대 크기 설정
	mp.fineness = 0.5;      	// 조밀도 값
	mp.quad_dominated = 0;    	// 삼각형 메시를 결합해 사각형 메시 우선 생성 활성화
	mp.elementsperedge = 2.0;
	mp.elementspercurve = 2.0;
	mp.grading = 0.2;   
	mp.closeedgeenable = 0;
	mp.closeedgefact = 1.0;
	mp.optsurfmeshenable = 1;

	// 메시 사이즈 분석 및 2D 표면 메시 연산
	Ng_OCC_SetLocalMeshSize(occ_geo, mesh, &mp);

	Ng_OCC_GenerateEdgeMesh(occ_geo, mesh, &mp);

	if (Ng_OCC_GenerateSurfaceMesh(occ_geo, mesh, &mp) != EXIT_SUCCESS) {
		std::cerr << "에러: 서페이스 메시 생성에 실패했습니다." << std::endl;
		Ng_DeleteMesh(mesh);
		Ng_Exit();
		return 1;
	}

	// OBJ 포맷으로 출력
	std::string output_filename = "output_mesh.obj";
	if (SaveMeshAsOBJ(mesh, output_filename)) {
		std::cout << " [성공] Quad 메시가 OBJ 포맷으로 정상 저장되었습니다: " << output_filename << std::endl;
	} else {
		std::cerr << " [실패] OBJ 파일 저장 중에 오류가 발생했습니다." << std::endl;
	}

	// 메모리 해제 및 종료
	Ng_DeleteMesh(mesh);
	Ng_Exit();

	return 0;
}