3D打印技术之切片引擎(4)

【此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺】

这一篇文章我讲一下多边打印的问题,多边打印是切片引擎的一项关键的技术,首先,它可以保证打印实体表面免受内部填充的冲击,保证外观的真实度;其次,在上层在相对于下层倾斜较大时,多边打印可以很好的起到支撑的作用,避免上层塌陷。

但是,目前来说,我的多边打印还不够普适,对一些不规范的模型,以及模型中非常尖锐的特征效果并不好,对绝大部分的较为平滑的模型是完全没有问题的。

下面就简单说一下它的原理:假设边界中的任意相邻的向量AB和BC,这里要找的是点d(角ABC中心线上的一点),看下图:

找出边界环中每一个相邻向量的d点,工作就基本完成了。所以原理非常简单,只不过是很多琐碎的细节需要处理好,比如说向量Bd的方向问题,B点和d点的欧氏距离等等,就不赘述,下面呈上代码。

void getAngularBisector(float3 &bisector,float3 point,float3 leftPoint,float3 rightPoint)
{
    float3 v1,v2;

    float norm1,norm2,angle;

    get_vector_diff(v1,leftPoint,point);

    get_vector_diff(v2,rightPoint,point);

    if(v1[0]*v2[1]==v1[1]*v2[0])
    {
        if(v1[1]==v2[1])
        {
            bisector[0]=0;

            bisector[1]=1;

            bisector[2]=0;
        }
        else if(v1[0]==v2[0])
        {
            bisector[0]=1;

            bisector[1]=0;

            bisector[2]=0;
        }
        else
        {
            bisector[0]=point[0]-1;

            bisector[1]=((v1[0]-v2[0])+(v1[1]-v2[1])*point[1])/(v1[1]-v2[1]);

            bisector[2]=0;
        }

    }
    else
    {
        getNormalizeVector(v1);

        getNormalizeVector(v2);

        if(v1[0]*v2[1]==v1[1]*v2[0])
        {
            if(v1[1]==v2[1])
            {
                bisector[0]=0;

                bisector[1]=1;

                bisector[2]=0;
            }
            else if(v1[0]==v2[0])
            {
                bisector[0]=1;

                bisector[1]=0;

                bisector[2]=0;
            }
            else
            {
                bisector[0]=point[0]-1;

                bisector[1]=((v1[0]-v2[0])+(v1[1]-v2[1])*point[1])/(v1[1]-v2[1]);

                bisector[2]=0;
            }

        }
        else
        {
            get_vector_sum(bisector,v1,v2);
        }
    }
}

void getInnerPoint(float3 &innerPoint,float3 point,float3 leftPoint,float3 rightPoint,float margin)
{
    float3 bisector;

    float distance,rate;

    distance=margin;

    getAngularBisector(bisector,point,leftPoint,rightPoint);

    rate=distance/sqrt(pow(bisector[0],2)+pow(bisector[1],2)+pow(bisector[2],2));

    innerPoint[0]=point[0]+bisector[0]*rate;

    innerPoint[1]=point[1]+bisector[1]*rate;

    innerPoint[2]=point[2]+bisector[2]*rate;

    if(get_vector3_det(point,rightPoint,innerPoint)<0)
    {

        innerPoint[0]=point[0]-bisector[0]*rate;

        innerPoint[1]=point[1]-bisector[1]*rate;

        innerPoint[2]=point[2]-bisector[2]*rate;
    }
}

void getInnerPoint(Phasor *innerPhasor,Phasor *phasor,Phasor*leftPhasor,Phasor *rightPhasor,float margin,int fillMaterial)
{
    getInnerPoint(innerPhasor->beginPoint,phasor->beginPoint,leftPhasor->beginPoint,phasor->endPoint,margin);

    getInnerPoint(innerPhasor->endPoint,phasor->endPoint,phasor->beginPoint,rightPhasor->endPoint,margin);

    innerPhasor->material=fillMaterial;
}

void getInnerBoundary(Phasor *&innerPhasors,Phasor *phasors,int phasor_num,vector<vector<int> > &closedSet
    ,float lineHeight,int fillMaterial,bool *innerBoundaryStatus)
{
    innerPhasors=new Phasor[phasor_num];

    int index,indexMain,phasorIndex,phasorIndexLeft,phasorIndexRight;

    float margin=lineHeight;

againScan:

    if(margin<0.1)
    {
        *innerBoundaryStatus=false;

        innerPhasors=NULL;

        return;
    }

    for(indexMain=0;indexMain!=closedSet.size();++indexMain)
    {
        int count=0;

        for(index=0;index!=closedSet[indexMain].size();++index)
        {

            phasorIndex=closedSet[indexMain][index];

            if(index>0)
            {
                phasorIndexLeft=closedSet[indexMain][index-1];
            }
            else
            {
                phasorIndexLeft=closedSet[indexMain][closedSet[indexMain].size()-1];
            }

            phasorIndexRight=closedSet[indexMain][(index+1)%closedSet[indexMain].size()];

            getInnerPoint(innerPhasors+phasorIndex
                ,phasors+phasorIndex
                ,phasors+phasorIndexLeft
                ,phasors+phasorIndexRight
                ,margin,fillMaterial);

            for(int i=0;i!=phasor_num;++i)
            {

                if(i==phasorIndex)
                {
                    continue;
                }

                if(get_vector_distance2(innerPhasors[phasorIndex].beginPoint,phasors[phasorIndex].beginPoint)>
                    get_vector_distance2(innerPhasors[phasorIndex].beginPoint,phasors[i].beginPoint))
                {
                    count++;

                    break;
                }
            }

            if(count>closedSet[indexMain].size()/5+1)
            {
                margin-=0.05;

                goto againScan;
            }
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 15:59:00

3D打印技术之切片引擎(4)的相关文章

3D打印技术之切片引擎(3)

[此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 从这一篇文章开始,我讲一下实体切片方面的一些技术. 切片引擎,实体部分大致包括: 提取边界矢量-->添加多边-->生成填充矢量集合. 其中最难的是生成填充矢量集合,也是整个切片引擎技术的核心,因为衡量一款引擎的好坏的四个核心要素--稳固性:与原始模型的相似度:用了多少材料:打印快慢,都是主要取决于填充矢量的生成技术.目前生成填充矢量的算法还有很多未知的问题有待攻克,对于这一块技术我将在最后与大

3D打印技术之切片引擎(5)

[此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 从这一篇文章开始,就开始说填充.在3D打印切片技术中,填充算法是最核心的部分.3D打印技术的常用的指标包括:打印速度,稳固性,柔韧性,逼真度,密度(关系着使用打印材料的多少),都与填充算法有着直接的关系.可以说衡量一个切片引擎的优劣主要看它的填充算法是否优越. 其实我开始研发切片引擎的时候,由于不是所有的模型打印都需要填充,所以前面的算法开发时间很短,大部分时间耗在了填充算法的研究上,也就是填充

3D打印技术之切片引擎(1)

切片引擎,是3D打印技术的灵魂,其实质就是将3D模型进行分层,输出矢量集合,是应该归为图形学的一门技术,其对数学算法要求很高,复杂性主要体现在要对3D模型的不同的拓扑结构做出判断并输出与之相符合的矢量集合.就我个人的观点,目前世界上最优秀的切片引擎在这一点上也没有做的很好,所以对于这一门技术,可进步的空间是很大的,未知的空间非常辽阔. 非常有幸的是在我的上一家公司里面,我有机会开发这样的一个模块,我负责由3D模型生成矢量集合,另一位同事把我生成的矢量集合再生成为Gcode,据我所知,目前国内还没

3D打印技术之切片引擎(2)

[此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 在上一篇文章中,我从总体上介绍了一下切片引擎技术,从这一篇文章开始,我开始说一下具体的技术细节. 切片引擎,实体部分包括: 提取边界向量-->添加多边-->生成填充向量集合. 还包括生成支撑向量集合.就先说下支撑算法. 生成支撑向量集合分为人工生成和自动生成两种,优越的支撑算法主要体现在 1,省材料. 2,生成速度快. 3,生成的支撑体与零件实体较少的接触与干涉,有利于剥离. 毕竟,切片引擎的

重庆用3D打印技术修复世界最大千手观音

近日,重庆市大足石刻景区在千手观音主尊修复工程中首次引入3D打印技术.记者在修复现场看到,缩小版的千手观音主尊像的3D打印模型比例为1:3,打印模型主要用于主尊像的形态修复.? 重庆市大足县宝顶山千手观音雕刻于南宋中后期,距今有800多年历史.整个石刻佛像,包括一个千手观音主尊和四个侍者,有7.7米高.12.5米宽.刻在15?30米高的悬崖上,覆盖了近88平米的崖面,是世界上最大的千手观音雕像.精密拋光? 这次针对千手观音的大型修复工作,是由政府拨款进行的.研究人员没有采用传统的模具和铸造的方法

LAIKA公司应用ProJet 660 色彩3D打印技术改变3D动漫脸部定格动画

LAIKA公司应用 ProJet 660 色彩3D打印技术改变3D动漫脸部定格动画 通过使用彩色3D打印机,我们不仅能够推动面部表情效能提升到一个新的水平,同时我们也能实现人物的脸部的细节和微妙变化水平.布赖恩?麦克莱恩 - 如果你曾经想知道建立3D动画制作需要进行多少工作,得到的答案是"很多,很多" - 特别是如果工作依靠被称为停止运动的技术.定格动画需要动画师捕捉每个操纵建模字符拼凑一个流畅自然的动作.例如只是一秒的面部表情动作,可能12到24种不同的模型改变是必需的. 实现一站式

苹果公司欲使用3D打印技术进行新产品的测试

苹果公司的产品是很多人都在追随的,作为世界上最大的电子产品的企业来说,因为它的产品给了人们更好的用户体验.怎么才能做到这一点呢,这就源于他们的输入设计实验室,这里可以称之为最隐秘并且先进的原型测试实验室其中的一个.这里有很多非常精密的仪器,也有很多为了完美产品的工作人员,不管是从外观体验感以及性能他们都希望能够带给大家完美的产品. 在最近一次苹果公司的公关活动中,他们向媒体展示了这个实验室,让它从神秘不为人知的背后走到了人们的面前,一方面表现出他们对于产品性能测试的重视,同时也向人们说明他们对于

3D打印技术让实现更多天马行空的创意

在3D打印技术还没有出现的时候,我们脑海中一些天马行空的想象是没办法实现的.也有很多创意相关的工作人员在叹息,似乎有一种生不逢时的遗憾.近年来,随着3D打印技术越来越成熟,自由设计成为一种优势弥补了一些在传统制造业的不足,似乎个性化的定制才是一种时尚和潮流的标志.在这样的背景下,一大批充满着个性化的创意产品走入人们的生活,让人们对创意有了更新更奇特的了解. 不久前在微博上热传的一组雕塑图片被很多人转发.一些具有重庆本土特色的方言被创意者形象的刻在了雕塑上,所以当人们看到最终的作品时很有感触.这组

3D打印技术的研究成果-3D打印机厂家

3D打印技术,是以计算机三维设计模型为蓝本,通过软件分层离散和数控成型系统,利用激光束.热熔喷嘴等方式将金属粉末.陶瓷粉末.塑料.细胞组织等特殊材料进行逐层堆积粘结,最终叠加成型,制造出实体产品.与传统制造业通过摸具.车铣等机械加工方式对原材料进行定型.切削以最终生产成品不同,3D打印将三维实体变为若干个二维平面,通过对材料处理并逐层叠加进行生产.不需要众多的人力,直接从计算机图形数据中便可生成任何形状的零件,使生产制造得以向更广的生产人群范围延伸. 然而,通过专项研究,3D打印主要的技术形式有